Xiang Ruan's Homepage

Anything I want to share with this world.

使用org-page搭建个人博客

背景

希望吃喝拉撒睡都能不离开emacs是天下所有emacser的共同毛病。作为emacser之一的我也绝对不会是例外。我很少更新博客,除了懒以外,最主要的问题就是没有找到足够好的emacs书写工具来更新博客(说到底还是因为懒,emacs人群的唯一共同点不就是懒吗)。

之前,并不是没有工具可以做到通过emacs维护博客。如果Google一下,可以找到很多类似的方法和工具,尤其是基于org mode的。但是由于各种各样的原因,所有这些方案都不尽人意。一位多年使用emacs的人,不可能不是A型血的臭讲究,你懂的。不讲究的话,打字直接用office不就得了。所谓眼里容不得沙子。哈哈。

在经过多方选定后,最终选定了org2blog。 这算是一个折中的相当不错的解决方案。它其实是wordpress的一个emacs前端,简单的说就是将emacs书写的文档直接发布到相应的wordpress网站上。通过这种方式,书写博客已经变得相当简单,书写者只需打开emacs,使用org2blog的命令开启一个新的post,通过org mode书写,然后再使用org2blog的相应命令发布就一切搞定。

因为有了org2blog,我开始同时维护两个网站,一个是对外的个人博客,一个是私有不公开的日记。在多年使用之后发现,日记每天都在坚持,但是个人博客几乎没有更新。究其原因,还是书写方式的问题,因为是wordpress,不够单纯,不够便捷。对个人日记而言,每天三言两语无所谓,但是在对外公开的个人博客上书写长文,就有诸多不爽了。没错,个人前端已经完全emacs化,但是博客本身最终还是一个wordpress平台。类似wordpress这样的平台,于我而言它的最大原罪是,它不是静态的(为什么要静态的,理解的同学会理解,不理解的同学可能很难理解),这会导致维护,备份,升级都很麻烦,而且不简洁,不够simple(不认同俺这个观点的同学,可能咱们认同的simple不是一个概念,这里就不展开了)。

在多年以后的最近,我终于找到了心目中的pure emacs解决方案,这就是这里要记录的org-page 。 org-page其实基于org-mode的一个静态网页生成器(static site generator),但是它被设计成个人博客工具,方便博主维护和书写静态的博客网站。

相对于org2blog,org-page有很多优点,这里省去细节 (请自行参考1 , 2 , 3 ),大略总结如下

功能 org2blog org-page
静态网站 no yes
tag,keyword, tab自由定制 yes yes
theme yes yes
可搜索 yes yes
用户评论 yes yes
pure emacs based no yes
版本管理 no yes(git based)

通过org-page建立个人博客

org-page虽然强大便利,但是它的使用说明实在简陋,按照官方的说明安装会遇到很多问题。另外,它的说明是以个人博客在github page为前提的,并没有提及如何在个人的服务器上建立博客,所有在最初安装的时候会感到诸多困惑。经过一番折腾后,我终于将各种设定搞定,这里总结一下。

需要注意的是: 这里的很多步骤,可能不是唯一的解决方案,而且有些看起来略显愚蠢,但是它是我安装时候最终work的做法,所以

  • 第一,我不保证我的做法在其他平台和环境下一定work,
  • 第二,我不保证所有步骤都是必须或者唯一的。

另外,安装之后还有不少使用上的问题,在最后会总结一下。日后解决后也会增补说明

环境说明

假设个人博客的服务器是blogserver,用于更新博客的客户端是client,服务器上的center git server在/home/user/blogging,服务器上的博客网页在/usr/share/blog,客户端的git clone是/data/repository/blog ( 此三项的具体意思会在后面具体说明)。总结如下

item content
server name blogserver
client name client
center git repo. /home/user/blogging
webpage /user/share/blog
local git clone /data/repository/blog

安装步骤

  1. 在客户端安装org-page

    clone一个[[https://github.com/kelvinh/org-page][org-page]] ,加入.emacs.d,load path。这个就不仔细说了。不过最简便的方式还是

    M-x package-list
    

    你懂的。

  2. 在~/.emacs(.el)里面添加org-page的设置

    (require 'org-page)
    (setq op/repository-directory "/data/repository/blog")
    (setq op/site-domain "http://blogserver")
    (setq op/personal-github-link "https://github.com/username") ; if you want to show a personal github link 
    (setq op/site-main-title "My Blog")
    (setq op/site-sub-title "Blah, blah...")
    (setq op/personal-disqus-shortname "username_of_disqus") ; use for disqus comments
    (setq op/personal-google-analytics-id "userid_of_google_analytics")
    

    需要用户评论功能的话,需要disqus账号,没有可以去申请一个

  3. 登录到blogserver, 创建center repository

    $ mkdir /home/user/blogging
    $ cd /home/user/blogging
    $ git init --bare
    

    因为要建立center repository,所以使用--bare

  4. 回到客户端client,创建一个local的repository。这个最好通过org-page来做。打开emacs,执行

    M-x op/new-repository
    

    当命令提示需要输入路径的时候,输入/data/repository/blog。之后org-page会创立一个本地的repository,其中会包含两个branch: sourcemaster 。简单的说,org-page的机理是在soruce branch下书写org文件,然后将html发布到master上去。这样实现源代码与博客网页html的分离

  5. 设置客户端repository的远程center repository

    $ cd /data/repository/blog
    $ git remote add origin ssh://username@blogserver:port/home/user/blogging
    $ git remote -v
    

    众所周知,如果ssh server是缺省port 22,上述的命令中:port可以省略。

  6. 将客户端的初始文件和branch上传到center git repository

    $ cd /data/repository/blog
    $ git push -u origin master
    $ git push -u origin source
    
  7. 下面的设置是为了在ssh到blogserver的时候无需每次输入密码。这样,再通过org-page发布post的时候也会方便很多 ( 4, 5

    首先确认~/下是否有.ssh文件夹,或者.ssh文件下是否有id_rsa和id_rsa.pub文件,如果有,可以跳过钥匙生成的步骤,如果没有

    1. 生成钥匙 6

      $ ssh-keygen # 生成公匙
      
    2. 复制公匙到blogserver 7

      $ ssh-copy-id user@blogserver -p port_num
      
    3. 测试一下

      ssh user@blogserver:port_num
      

      正常的话,应该不用密码直接就登录到blogserver上了

  8. 登录到blogserver上,建立博客网站文件夹,其实就是一个center git repository的local clone

    $ mkdir /usr/share/
    $ git clone /home/user/blogging blog
    
  9. 设置apache,开通博客网站

    有N多方法,但是我假设博客就是http://blogserver ,就是说是在root下面。所以,很简单,编辑/etc/apache2/sites-available/000-default.conf, 替换 DocumentRoot /var/www/htmlDocumentRoot /usr/share/blog ,替换 <Directory /var/www/html><Directory /usr/share/blog> ,然后重启服务

    /etc/init.d/apache2 restart
    
  10. 几乎是最后一步了,设置git hook

    org-page的工作流程是,在客户端书写org,更新local repository,然后push到center repository,之后服务器上的博客网页(记住,其实就是center repository的一个本地clone)通过git pull来更新。问题在于,如果每次从客户端更新到center repository后,还要再登录到server上,手动pull到网页文件夹去,实在太可怕了。

    解决方法很简单,使用git的hooks功能。post-update是最合适的一个hook,就是一旦有了更新,更新结束后发个notification (8 ) 。所以,设置如下,

    cd /home/user/blogging/hooks
    cp post-update.example post-update
    

    编辑post-update,添加内容如下 ( 9 , 10 )

    cd /usr/share/blog
    env -i git pull
    
  11. DONE,回到客户端,打开emacs,可以书写博客了。

    org-page的具体用法,会另开帖子说明,这里把最常用到的命令简单的罗列一下

    命令 说明
    M-x op/new-post 打开一个新帖子
    M-x op/do-publication 发布一个新帖子
  12. 更新博客流程

    这部分可能很多人觉得莫名其妙,怎么搞得这么复杂? 不是一个 op/do-publication 就搞定了吗?是的,supposed to be, 但是很多问题搞不定,具体参考“残留问题”章节。所以如果你没有遇到我遇到的问题,那就忽略这步吧

    1. 确认当前repository在source branch下,if not, git checkout source
    2. open emacs, M-x op/new-post
    3. write your blog and save it
    4. git add new blog (under source branch) and commit it ( in emacs, you can use magit, it would be much easier to do the process)
    5. git push source, push source到center branch。这个不是必须的,因为博客本身只需要html文件,也就是master的文件。但是既然有了center server,何不把source备份呢
    6. M-x op/do-publication, 第一个问题选择y,第二个问题选择no,因为不用发布到其他文件夹,第三第四个问题选择y
  1. 图像链接

    将图像放到某个文件夹中,然后在post的org文件中用相对路径指定图像。publish的时候org-page会自动push和安排相应文件到remote端。比如在blog文件夹下做一个imgs文件夹,将图像a.jpg放入其中,在打开一个new post,指定category为blog的情况下,链接图像可以写成如下形式

    [[imgs/a.jpg]]
    

残留问题

终于可以享受full emacs based的博客更新了。但是依然还有一些令人头疼的问题需要解决。不知道是org-page原本如此,还是我的设置或者使用有问题。

  • 必须手动更新source branch之后才能发布

    如前所言,org-page的流程是,在source branch下书写org的文档,然后发布html到master下面去。所以在checkout到source的状态下,使用op/new-post打开一个新帖子,写好后保存。这时,按理说, op/do-publication就直接发布搞定了。问题是,我这里会失败,org-page无法发布到master中去。究其原因是,在source下新打开的帖子(或者修改后的老帖子)没有commit,必须手动add帖子,然后commit之后,才能op/do-publication

  • auto push remote失败

    要注意: 一定要设定ssh无密码登录,如果需要输入密码,op/do-publication就会失败

  • source push问题

    这个严格讲不算是一个问题,只是我个人的喜好。因为博客网页只需要html,所以org-page在发布的时候只push master到远程去。为了在远程center repository备份source,每次都需要手动push source。不知道org-page能不能提供选项每次连动source一起push一下。

Comments

comments powered by Disqus