上周末闲着没事干突然想把博客从 Wordpress 迁移到 Github pages 上,于是周日花了一天时间做迁移,期间各种折腾,终于变成了现在这样还算满意的情况。虽然我已经好久不写博客了,但俗话说“书非借不能读也”,博客这一迁移也激起了我重新写博客的欲望。再说,这个博客还身兼重任,那就是——养媳妇!哈哈~还是说说迁移中遇到的乱七八糟的问题吧~
搭建本地环境
首先,自然是在自己的 github 上面 new 一个 repository 了,名字必须是yourname.github.com
,虽然现在 github pages 的地址已经改为yourname.github.io
了,但我还没有尝试过 repository 用 io 结尾行不。
完成以后,就是各种本地的设置了,搭建 git 环境,搭建 ruby 环境啊一类的,这里就不详细说了,ruby 环境的搭建推荐使用RVM,很方便的说,当然,貌似不支持 windows。。。如果在 widnows 下我推荐使用云 IDE,就好像浏览器里的虚拟机,editor+terminal
,我常用Nitrous.IO
,给个我的推荐链接,有兴趣的可以试试。
然后就要在本地安装Jekyll
了,一句话gem install jekyll
搞定。Jekyll是一个 ruby 编写的静态站点生成器,在 github 上搭博客就靠它。但直接用 jekyll 貌似外观太朴素了,推荐直接使用jekyll-bootstrap,从名字就可以看出,这玩意把来自 twitter 的优秀 CSS 框架bootstrap
结合进来,很多漂亮的主题可以选择,而且内置了很多常用的功能。直接从jekyll-bootstrap
起步吧,先 clone 下来,然后把 remote 的地址改成自己的~
1 | git clone https://github.com/plusjade/jekyll-bootstrap.git yourname.github.com |
然后jekyll serve
就可以在本地localhost:4000
看到博客的样子,当然,现在空空如也~
先换主题
在导入文章进行各种设置之前,推荐先选一个自己喜欢的主题换上,因为后面很多定制涉及到修改主题文件,为了避免 2 次修改,先换一个主题比较方便。jekyll-bootstrap
提供了一个主题预览网站,上面就有很多不错的主题。点击页面下面的主题名字进行预览,选择喜欢的以后,点击蓝色的Install Theme
按钮,复制里面的代码执行,比如我选择的hooligan
,代码如下:
1 | rake theme:install git="https://github.com/dhulihan/hooligan.git" |
其中第一行将主题下载到_theme_packages
里面,第二行切换到新主题。现在本地预览就可以看到新主题了。主题有两个相应的文件夹,一个是_includes/themes/xxx
,这里放的是网页模板,另一个是 assets/themes/xxx
,这里放的主题用到的 css/js 文件。我们要定制页面显示的内容通常修改第一个文件夹的东西,定制样式修改第二个,后面遇到了详细说。
Wordpress 的文章迁移
现在可以导入原来的文章了,这个就比较闹心了,我的折腾时间有很大一部分花在这上面。官方文档专门讲解了各个常用的博客系统怎么迁移过来,wordpress 的步骤也不复杂,从管理后台导出 xml,然后执行一条命令即可将所有文章转换成.markdown
,将其拷入_post
文件夹即可。这个时候你本地预览就可以看到文章,标签以及分类信息了。闹心的事情来了,为什么我预览报一堆错误?为什么我的显示跟预期的不一样?唉,一个一个说吧~
乱七八糟的Could not find ref_id
这个问题浪费了我不少时间,最后发现原来是字符转义的问题!markdown
语法里中括号[]
是特殊字符,如果你的文章里出现则需要转义,加\
号即可。Too Simple!
公式的显示
以前研究学术的时候写过好几篇满是公式的博文,原先 wordpress 里貌似用的是一种插件,到这里显然行不通了。一番搜索后发现一个叫MathJax的牛逼东西,用 js 来渲染公式。在_includes/themes/hooligan/default.html
里加入
1 | <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"> |
即可,这样就可以用$$$$作为开始结束符来输入公式了。注意这里的hooligan
是你的主题名称,你的主题如果是别的就改成相应别的。这样的公式是独占一行的,如果要输入 inline 的公式,则还需要添加
1 | <script type="text/x-mathjax-config"> |
这样,使用$
作开始结束符就可以输入行内的公式了。这里有个坑,有可能会遇到类似Liquid Exception: Variable xxx was not properly terminated with regexp xxx
,这个我搜了半天,最后发现是公式内需要显示大括号时,原来会输入\{\}
,但 jekyll 中\
也需要转义,改成\\{\\}
即可。同样的问题还有公式换行的时候,原先的\\
改成\\\\
才行。有时[]
也需要转义。转义——多么痛的领悟。
代码高亮
把博客整到 github 上的应该多半都是程序员吧,博客自然少不了一堆公式。在 github 上直接用类似
1 |
|
即可,但不知道为什么我的高亮一直没发生效,后来还是乖乖的用
1 | {% highlight python %} |
虽然写起来稍显复杂,但高亮效果不错,配合我的主题非常好看。另外,在写这篇文章的时候我又遇到一个问题,如何显示标签,比如像上面的代码里带有标签该如何转义书写呢,这个问题我也折腾了好久,很多人说用 大段代码的显示推荐使用 github 的gist,否则转义累死人啊!上面的大段代码就是用的 gist 显示的,配合了自定义的 gist 样式。这里值得说一下,gist 也是个坑!关于在 jekyll 嵌入 gist,可以使用官方的方案,直接写 一切就绪,push 到 github 去吧,相信很多人遇到过这个问题:明明我本地预览正常,为啥 push 到 github 不生效呢?快去查查邮箱,有没有收到 github 给你发的 好了,博客现在差不多了,但对美有要求的你应该不会停止。"
进行嵌套,能解决问题,但是有点搞不清楚为啥这么写,后来发现,原来官方早就给答案了,把内容放到{% raw %}{% endraw %}
和{{ "{% endraw "}}%}`里面就不会进行 tag 解析了。
### 图片迁移
博客搬过来了,图片不多的话自然也搬过来吧~在`assets`文件夹下新建文件夹`images`和`files`,一个用来放图片,一个用来放文件附件。然后为了方便引用这两个路径,可以在`_config.yml`里定义变量:
1
2img_url: /assets/images
file_url: /assets/files1
2
3var duoshuoQuery = {
short_name: {% raw %} "{{ site.JB.comments.duoshuo.short_name }}" {% endraw %}
};1
2
3
4comments:
provider: duoshuo
duoshuo:
short_name: xxxx1
2{% raw %}{% when "duoshuo" %}{% endraw %}
{{ "{% include JB/comments-providers/duoshuo "}}%}1
2
3
4
5
6
7
8<section>
<h3>Latest Comments</h3>
<ul class="ds-recent-comments" data-num-items="10" data-show-avatars="0" data-show-time="0" data-show-title="0" data-show-admin="0" data-excerpt-length="18"></ul>
</section>
<section>
<h3>Recently Visitors</h3>
<ul class="ds-recent-visitors" data-num-items="4" data-avatar-size="45" style="margin-top:10px;"></ul>
</section>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77---
layout: page
title: 进击的马斯特
tagline: Go Fighting! Master!
---
{% for post in paginator.posts %}
<div class="post-wrapper">
<h2 class="h2 entry-title">
<a href="{{ post.url }}">{{ post.title }}</a>
</h2>
<div class="entry-meta">
<i class="icon-user"></i> <span>{{ post.author }}</span>
<i class="icon-calendar"></i> <span>{{ post.date | date:"%Y-%m-%d" }}</span>
{% unless post.categories == empty %}
<i class="icon-bookmark"></i>
{% for category in post.categories %}
<a href="/categories.html#{{ category }}-ref" target="_blank">
<span class="label post-category">{{ category }}</span>
</a>
{% endfor %}
{% endunless %}
{% unless post.tags == empty %}
<i class="icon-tag"></i>
{% for tag in post.tags %}
<a href="/tags.html#{{ tag }}-ref" target="_blank">
<span class="label post-tag">{{ tag }}</span>
</a>
{% endfor %}
{% endunless %}
</div>
<br /><br />
<div class="entry">
{{ post.content | split: '<!--more-->' | first }}
<p>
<a href="{{ post.url }}/#more" class="more-link btn">
<span class="readmore">阅读全文 »</span>
</a>
</p>
</div>
</div>
<br />
{% endfor %}
<!-- Pagination links -->
<div class="pagination pagination-centered">
<hr />
<ul>
<li class="disabled"><a>{{ paginator.page }} / {{ paginator.total_pages }}</a></li>
<li><a href="/">«</a></li>
{% if paginator.previous_page %}
{% if paginator.previous_page == 1 %}
<li><a href="/" class="current"><</a></li>
{% else %}
<li><a href="/page{{paginator.previous_page}}/"><</a></li>
{% endif %}
{% else %}
<li class="disabled"><a><</a></li>
{% endif %}
{% for count in (2..paginator.total_pages) limit:6 %}
{% if count == paginator.page %}
<li class="active"><a>{{count}}</a></li>
{% else %}
<li><a href="/page{{count}}/">{{count}}</a></li>
{% endif %}
{% endfor %}
{% if paginator.next_page %}
<li><a href="/page{{paginator.next_page}}/">></a></li>
{% else %}
<li class="disabled"><a>></a></li>
{% endif %}
<li><a href="/page{{paginator.total_pages}}/">»</a></li>
</ul>
</div>
<br />
<br />filter
方式,先以<!--more-->
调用split
分割,然后用first
取前面即可。其实我不太明白为什么直接写{{"{{ post.content.split('!--more-->').first "}}}}
为啥不行。。。有懂的可以告诉我~后面的部分就是分页的页码了,我这里为了风格统一,套用了bootstrap
的分页样式,具体可以看bootstrap
的分页文档。这样“高大上”的首页就诞生了。
大段代码的显示
<script src="https://gist.github.com/yourname/xxx.js"></script>
,也可以用 jekyll 的 gist 标签:{% raw %}{% gist xxx %}{% endraw %}
。很不幸,这两种方案都有问题,本地预览时正常显示,但上传到 github 后发现,gist 后面的内容被截断,匪夷所思。经过一番算搜索发现,又是 jekyll 的标签解析惹得货啊。详细可以看这两篇文章:Fixing your embedding gist snippets 和 Why don’t self-closing script tags work?。简单来说就是,这两种方式会生成<script src="https://gist.github.com/yourname/xxx.js" />
这样的标签,而很多浏览器解析这样的“自关闭标签”有 bug,很奇怪吧,非常简单的问题居然有 bug!!那怎么破呢,非常简单,加个空格即可,如:<script src="https://gist.github.com/yourname/xxx.js"> </script>
。push 到 github 时没效果
page build failure
邮件啊,我是收到过五六封。。。其实这是因为 github 为了安全考虑禁止使用第三方插件,所以首先删除你_plugins
文件夹下除了debug.rb
以外的其他文件,然后本地预览时使用jekyll serve --safe --watch
命令,--safe
确保满足 github 的安全要求,--watch
可以不用重启 jekyll 使修改即时生效。总结
jekyll-bootstrap
由于是以bootstrap
为基础的,所以熟悉前端的孩子修改起来特别方便,比如首页加个侧边栏,各种样式修改,加入font-awesome
图标等等,慢慢探索吧~用bootstrap
的另外一大好处就是,这个框架本来就是响应式的,所以不用费心去像 wordpress 一样装个插件去优化手机版,各种尺寸的屏幕都能做到自适应,非常方便!快把你的博客也迁过来吧!