ZMonster's Blog 巧者劳而智者忧,无能者无所求,饱食而遨游,泛若不系之舟

使用Github Pages服务建立个人博客

为什么要使用Github Pages来建立个人博客

使用什么博客平台取决于个人的需求,因此,并不是所有人都适合使用本文介绍的这种形式,一般来说,追求简洁的一些程序员可能会使用这种方式。

对于有以下需求的人来说,使用Github Pages建立博客是个好主意:

  • 希望能在本地编写文章
  • 追求简洁、轻便
  • 不想购买主机空间和域名

第一条,本地编写允许文章允许用户选择自己喜欢的编辑器来进行写作,而不是使用博客平台的编辑器——对于我等emacser来说,许多博客平台的编辑器功能实在是有点不够看。著名的博客平台WordPress 提供xml-rpc接口,允许用户通过相关软件在本地编写好文章后远程发布。说实话,我还是比较喜欢WordPress的,但它不满足后面三个需求。说到xml-rpc,早些年国内各大博客平台都是支持xml-rpc借口的(如CSDN,ChinaUnix等),但是后来据说是出于安全因素的考虑,似乎有些网站是关闭了这个接口,现在网上的相关搜索结果普遍是四五年前的讨论结果。新浪以前似乎也支持xml-rpc接口,但据我测试现在是无法进行发布了,CSDN貌似也有点问题,应该是关闭了接口。之所以要说xml-rpc,是因为emacs有一个插件org2blog能够通过xml-rpc接口来进行远程发布,顾名思义org2blog是使用org-mode作为major-mode的,熟悉org-mode并且正在使用WordPress的朋友一定会喜欢这个插件,如果需要,可以到这个链接 下载org2blog,此外org2blog依赖xml-rpc.el,点这里 可以下载。

第二条,还是说WordPress吧,WordPress是使用php编写的,使用mysql数据库来管理文章。从功能上来说WordPress是非常好的,它提供丰富的主题、插件以及拥有很多用户的论坛(好吧我不是在这里推荐WordPress的,不过我确实挺喜欢WordPress,之前也说过了),与此相对应的,为了完全了解WordPress,用户不得不去学习如何安装它的主题和插件、熟悉选项繁多的后台管理界面。至于国内的一些博客平台,外观暂且不说,一般都带有很多广告,我特别讨厌这一点。

第三条,好吧这是我选择这一条路的主要理由,你懂得,我很穷,没有钱买主机空间和域名(求一个土豪朋友)。为什么我穷?因为我现在待业在家,没有工作——没有工作是因为我把工作辞了在家准备考公务员,至于这后面的故事就很复杂啦,如果有兴趣的话可以发邮件给我和我谈谈心哟。

如果看到这里您对我的观点基本赞同的话,您可以继续读下去,否则我觉得您可以考虑一下WordPress或者其他平台。

Github Pages是什么

Github 是一个用于使用Git版本控制系统项目的共享虚拟主机服务[1]。简单说,它是一个具有版本管理功能的代码仓库,每个项目都有一个主页,列出项目的源文件。

github.png

但是对于一个新手来说,看到一大堆源码,只会让人头晕脑涨,不知何处入手。他希望看到的是,一个简明易懂的网页,说明每一步应该怎么做。因此,Github就设计了Pages功能,允许用户自定义项目首页,用来替代默认的源码列表。所以,Github Pages可以被认为是用户编写的、托管在Github上的静态网页。

Github提供模板,允许站内生成网页,但也允许用户自己编写网页,然后上传。有意思的是,这种上传并不是单纯的上传,而是会经过Jekyll程序的再处理。这里的Jekyll 是一个静态站点生成器,它提供了模板、变量、插件等功能,所以实际上可以用来编写整个网站。它也是Github Pages的后端处理工具。

利用Github Pages的这些特点,我们就可以搭建一个个人的博客——虽然是静态的网站,不过足够了。

环境准备

对于想使用Github Pages服务来建立个人博客的朋友来说,您需要以下环境:

  • Github帐号
  • 配置好的本地git工具
  • markdown编辑器或者其他的编辑器
  • Jekyll(可选)

前面两个我不想多说,相关的文章太多了,在这里重复那些内容没有什么意义。

特别要说的是,建议使用linux系统,虽然理论上windows也可以使用msysgit来管理,但我不认为那是个好主意,当然如果愿意折腾,就无所谓了。

至于markdown,它的语法简单明了,很快就能上手,因此不要担心这个问题,需要学习的话,可以到Github的首页,按下键盘的 M 键进行学习。至于编辑器,简单的文本编辑器如gedit、leafpad甚至nano都可以,当然,本人选择使用emacs并且不使用markdown模式而是坚持使用org-mode,感兴趣的可以在文章尾部找到相关的配置以及使用方法。此外一些支持markdown语法的编辑器也是比较好的选择。

最后的Jekyll为什么标注是可选呢?因为我们并不需要对相关的项目仓库做什么特别的事情,我们只需要写文章,然后commit->push就是了,之所以需要Jekyll,是为了方便本地预览博客以及进行调试。怎么说也要保证自己的网站确实能够运行然后才去让别人阅览吧?总而言之,Jekyll并不是建立博客必须的部分,但它是帮助我们更好地进行管理的工具。

Jekyll的安装:

#以debian系linux发行版为例
sudo apt-get install rubygems1.8
gem install jekyll liquid open4 maruku classifier rdiscount

方案选择

可选的方案有三个:

Jekyll-Bootstrap和Octopress是两个基于Jekyll的博客框架,使用它们能够快速地得到一个基本好看的、能够运行的博客系统,不过还是那个问题,因为已经够用了,所以你不会去关心它们到底干了什么怎么干的,直到你遇到问题。不过它们还是不错的,这是真心话。相对来说我个人比较推荐Jekyll-Bootstrap,因为它在Jekyll的基础上并没有作太大的改变,只是增加了主题和一些配置而已,Octopress干的事就多了。

这里主要说一下第三种方案。

自己动手呢,也分两种情况:

  • 复用他人的博客模板
  • 自行编写每一行网站代码

显然第二种情况是如果不是对前端知识足够熟悉是比较困难的。因此复用他人的博客模板是比较好的选择,这里的复用并不是简单的拷贝然后使用(当然你想的话也可以),其他人的博客一般都会有一些细节无法满足自己,所以还需要自己进行修改、定制,这个过程就是意义所在。

这个页面 收集了非常多Jekyll博客的链接及其源代码,我比较喜欢codepiano的风格,然后我最初用来学习的是唐九军的博客,唐九军的博客没有使用Jekyll-Bootstrap等其他东西,完全是自己编写的css和js,其文件结构也比较清晰——这两个人的博客和源代码链接都可以在刚才说的页面上找到,请善用快捷键 Ctrl+F

行动纲领

按照以下步骤进行:

  1. 在Github上建立一个名为<username>.Github.io的repo,其中的username为Github用户名.
  2. 在本地建立对应的repo目录并设置好.
  3. 将下载下来的模板拷贝到本地repo目录中.

前期的工作就是这么三步,当然这里说得比较简略,详细的步骤可以到Github Pages的帮助页面 里进行了解。后面主要的工作集中在对自己的博客的配置中,下面将讲述博客配置的一些细节。

Jekyll博客配置

之前说Jekyll并不是必须的,但这里为什么要说“Jekyll博客配置”呢?因为虽然我们可以不用Jekyll,但最终Github pages生成我们的博客时就是用的Jekyll,所以我们在配置上还是得按照Jekyll的规矩来。

博客目录结构

首先明确一点,博客目录中不以下划线为命名开始的文件/文件夹都会在生成博客时复制过去,根据个人的不同喜好,博客的结构会不一样,这里只说一下Jekyll要求的一些结构:

-- index.html         网站首页文件
-- _layouts           博客模板目录
   -- default.html
   --post.html
-- _posts             文章存放目录
   -- 2013-09-08-test.md
   -- 2013-09-08-test.html
   -- <other posts>

除此以外其他文件都不是必须的,但光有这三个东西很难保证能生成一个足够完整的博客——事实上网站模板和文章目录也不是必须的,除了index.html,因为完全可以乱七八糟写一堆html文件然后自己在各个html文件之间理清关系。因此,通常的一个功能完整的Jekyll博客目录包含以下结构和文件:

-- index.html         网站首页文件
-- archives.html      文章存档页面文件,文件名可改
-- categories.html    文章分类页面文件,文件名可改
-- tags.html          文章标签页面文件,文件名可改
-- about.html         “关于我”页面文件,文件名可改
-- rss.xml或atom.xml  博客feed文件,文件名可改
-- sitemap.xml        博客地图,为博客做SEO优化,这个我不太懂
-- _config.yml        Jekyll博客配置文件
-- _layouts           博客模板目录
   -- default.html
   -- post.html
-- _includes          可复用的公用模板文件目录,例如博客的导航条。不是必须的,
                      但分离出各个页面的公有部分可以使得模板更易读,结构更清晰
   -- footer.html
   -- footer.html
   -- <other file to include in template>
-- _posts             文章存放目录
   -- 2013-09-08-test.md
   -- 2013-09-08-test.html
   -- <other posts>
-- assets/            其他博客文件存放目录,如css,图片,js文件,目录结构仅为
                      示例,可根据个人意愿自行设置
   -- css
      -- style.css
   -- img
      -- favicon.ico
   -- js
      -- blog.js

博客模板

正如上面的示例一样,博客模板一般包含一个default.html和一个post.html,正如其名字一样,default.html是博客的模板,而post.html一般是文章的生成模板。查看一些Jekyll博客的模板,您会发现其中会有

{{ site.url }} {{ for post in site.posts }}

这样的语句,这是因为Jekyll使用liquid语法 来解析模板,诸如 site.urlsite.posts 这样的部分是Jekyll内置的一些变量,关于Jekyll的变量的更多内容可以到Jekyll的官网 上深入了解。

有了模板文件后,其他的页面都可以通过Jekyll所谓的front-matter来使用模板,举例来说,撰写文章时,一般这样写:

— layout : post title : <文章标题> categories : <分类> tags : <标签> — <正文> …

这样在编写文章时就只需要关心文章内容了。

_config.yml

_config.yml文件是Jekyll博客的配置文件,用户可以在这个配置文件中设定博客名称、博客描述、作者名称等信息,并可以在模板中作为变量使用。

我的配置文件如下所示:

permalink:        /:year/:month/:day.html
markdown:         rdiscount
pygments:         true
paginate:         5

title:            笼中梦
url:              http://linusp.Github.io/
feed:             /atom.xml
author:
    name:         发条兔子
    email:        linusp1024@gmail.com
    description:  "变成兔子的青蛙"

follow:
    email:        linusp1024@gmail.com
    Github:       https://Github.com/Linusp


desc:      发条兔子的不完全技术博客

indexContent:     true

style:            /assets/css/style.css
blogName:         笼中梦
blogDesc:         发条兔子的不完全技术博客
favicon:          /assets/img/favicon.ico
theme:            blue

disqus:           linuspb

copyright:        © 2013
test:             ok

archives页面示例

一个简单的archives页面[2]如下

---
layout: default
title : Archives
---
<ul>
  {% for post in site.posts %}
  <li>
    <a href="{{ post.url }}" title="{{ post.title }}">
      <span class="date">
        <span class="day">{{ post.date | date: '%d' }}</span>
        <span class="month"><abbr>{{ post.date | date: '%b' }}</abbr></span>
        <span class="year">{{ post.date | date: '%Y' }}</span>
      </span>
      <span class="title">{{ post.title }}</span>
    </a>
  </li>
  {% endfor %}
</ul>

同样的,categories页面和tags页面的形式差不多,也是使用Jekyll内置的变量,当然要做得好看还是要费点功夫的,比如说本人这个博客的这两个页面还是一团糟(因为博客主题的作者并没有提供这两个页面,这就是所谓 自己动手丰衣足食 啦)。

_site目录

本地调试时,Jekyll会在目录下生成一个_site目录,目录就是真正生成的博客目录和文件,但这个文件对Github Pages是无意义的,仅仅是用来方便本地预览和调试,因此建议在.gitignore文件中添加该目录以在push时不用上传该目录及其中的文件。

使用emacs的org-mode

对于emacser来说,使用org-mode来写作才是最幸福的事情,因此就有了这一部分。这一部分的绝大部分内容来自脚注2[2]中提到的文章,基本的配置过程和要点在文章中都已经说得很详细了,因此我在这里就简略地说几点。

因为Jekyll可以识别markdown文件和html文件,所以使用emacs的org-mode将org文件publish成html文件就是我们要做的。值得一提的是Jekyll-Bootstrap在本地调试时直接无视_posts目录下后缀为html的文件,虽然说肯定有办法改变这种行为,但我找了一会没找到就放弃了,加之Jekyll-Bootstrap在Jekyll的基础上又多加了一些东西,所以导致我并没有去使用Jekyll-Bootstrap以及使用了Jekyll-Bootstrap的博客模板。

我的方案:

  1. 建立一个目录,在其中建立两个子目录,一个名为 org ,一个名为 Jekyll 。后者是和username.Github.io这个repo对应的本地repo目录,前者是org格式的文章存放目录,注意org目录下再建立一个 _posts 目录,将文章存放到 org/_posts 下面,这样在执行 org-publish-project 时才能保证生成到指定目录。
  2. 使用org-mode 7.x。emacs23自带的org-mode版本为6.x,其中的bug会导致插入的front-matter在生成时发生错误。emacs24自带的org-mode工作良好。
  3. org-mode的publish参数中一定要加上 :body-only t 否则就会生成完整的html文件,这不是我们想要的。
  4. 编写文章时,在头部添加front matter,如下
#+BEGIN_HTML
---
layout     : post
title      : 使用Github Pages服务建立个人博客
categories : IT
tags       : Github emacs org-mode Jekyll
---
#+END_HTML

而不需要其他信息,并在之后编写正文。

我的publish配置(仅供参考)

(require 'org-publish)
(setq org-publish-project-alist
      '(
    ("org-linusp"
     ;; Path to your org files.
     :base-directory "~/blog/org/"
     :base-extension "org"
     ;; Path to your Jekyll project.
     :publishing-directory "~/blog/Jekyll/"
     :recursive t
     :publishing-function org-publish-org-to-html
     :headline-levels 4
     :html-extension "html"
     :body-only t ;; Only export section between <body> </body>
     )
    ("org-static-linusp"
     :base-directory "~/blog/org/"
     :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|php"
     :publishing-directory "~/blog/Jekyll/"
     :recursive t
     :publishing-function org-publish-attachment
     )
    ("blog-linusp" :components ("org-linusp" "org-static-linusp"))
    ))

执行 org-publish-project 时,选择 blog-linusp 进行publish(按照我这个配置)。

[1]详情见维基百科的Github条目. [2]来自Using org to Blog with Jekyll.