纪录一下这次把 blog 迁移到 Jekyll 时遇到的问题
1. Jekyll 是一个静态页面生成器
首先要记住的是 Jekyll 是一个静态页面生成器,所以不会有用户系统,不会有权限控制,很多常规站点有的东西它都没有。 如果需要一些高级功能,优先的选择就是 javascript + 外部服务,比如评论可以用 disqus, 搜索可以用 google search。
2. 文档位置
- Jekyll Template Data: 主要是 site, page, paginator 的详细说明。
- Liquid: Jekyll 使用的模板系统是 liquid, 这个是 liquid 的使用手册。
- Jekyll Sites: 范例站点,如果实在某个功能不知道如何实现,就可以在这页找找,也许有人实现过。
3. sitemap.xml, rss.xml, atom.xml
这个其实比较简单,因为 Jekyll 的模板系统支持 xml, 范例可以参考这个站点的源码,另外 Jekyll 系统的 post 只有一个实践,如果你更新了一个 blog, 并且想在这些文件中体现,你需要在你的 post 中引入一个新的变量,并在模板文件中体现,比如 post 的 头部如下所示:
--- | |
layout: post | |
title: 机房网段更改后,如何避免在机房逐台更改IP? | |
lastmod: 2012-06-01 | |
--- | |
some text |
然后 site.xml 如下所示
--- | |
layout: nil | |
--- | |
<?xml version='1.0' encoding='UTF-8'?> | |
<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'> | |
{% for post in site.posts %} | |
<url> | |
<loc>{{ site.url }}{{ post.url }}</loc> | |
{% if post.lastmod %} | |
<lastmod>{{ post.lastmod | date_to_xmlschema }}</lastmod> | |
{% else %} | |
<lastmod>{{ post.date | date_to_xmlschema }}</lastmod> | |
{% endif %} | |
</url> | |
{% endfor %} | |
</urlset> |
4. tag, category
其实这两个功能很类似,我的站点就只使用了 tag, 没有用 category。 tag 的使用比较简单,把头部加入如下的一行即可。
tags: linux debian qterm
如果你的 tag 中可能含有空格,也可以使用
tags: ["et al", "foo bar"]
4.1 生成 tag 列表页
如果想偷懒,直接把 tag 链接到 google search 即可,但那样的结果不太准确,我的方法是分两步
- 用 Rakefile 中生成所有 tag 的文件
- 引入一个 tag 专用的 layout
生成 tag 文件的代码如下:
desc 'Generate tags page' | |
task :tags do | |
puts "Generating tags..." | |
require 'rubygems' | |
require 'jekyll' | |
include Jekyll::Filters | |
options = Jekyll.configuration({}) | |
site = Jekyll::Site.new(options) | |
site.read_posts('') | |
site.tags.sort.each do |tag, posts| | |
html = <<-HTML | |
--- | |
layout: tag_index | |
tag_name: "#{tag}" | |
title: Postings tagged "#{tag}" | |
--- | |
HTML | |
File.open("tags/#{tag}.html", 'w+') do |file| | |
file.puts html | |
end | |
end | |
puts 'Done.' | |
end |
tag 的 layout 文件
--- | |
layout: default | |
--- | |
<h2 id="approx">Postings tagged "{{ page.tag_name }}"</h2> | |
<ul class="posts"> | |
{% for post in site.tags[page.tag_name] %} | |
{% include post_as_li.html %} | |
{% endfor %} | |
</ul> | |
{% include disqus_count.html %} |
4.2 生成 tag cloud
我个人对 tag cloud 没有兴趣,所有只做了 tag lists, 不过方法类似,同样也是用 Rakefile,范例如下
desc 'Generate tag cloud' | |
task :tag_cloud do | |
puts "Generating tag_cloud..." | |
require 'rubygems' | |
require 'jekyll' | |
include Jekyll::Filters | |
options = Jekyll.configuration({}) | |
site = Jekyll::Site.new(options) | |
site.read_posts('') | |
html = '<h4>Tags</h4><ul class="tag-cloud">' | |
site.tags.sort_by{|k,v| -v.count}.slice(0,10).each do |tag, posts| | |
html << <<-HTML | |
<li><a href="/tags/#{tag}.html">#{tag}(#{posts.count})</a></li> | |
HTML | |
end | |
html << '</ul>' | |
File.open("_includes/tag_cloud.html", 'w+') do |file| | |
file.puts html | |
end | |
puts 'Done.' | |
end |
然后在你的 sidebar 中 include 生成的文件即可。 category 也是类似。每次更新后运行 rake build
即可 (build 依赖前面的两个任务)。
5. PS1
在 markdown 文件中 embed gist 文件时,记得把 </script> 放在第二行,比如
<script src="https://gist.github.com/2863678.js?file=gistfile1.rb"></script>
会导致所有之后的文字不显示,改成如下形式后即可工作
<script src="https://gist.github.com/2863678.js?file=gistfile1.rb">
</script>
6. PS2
当你想写一篇关于 jekyll 的文档时,请尽量把所有可能会导致 jekyll 错乱的代码都扔到 gist, 否则就会像我一样,发布到第4次才成功,尽管你的代码在本地能正常运行。