从Ghost迁移到Hexo

前言

迁移的原因,大概是因为node的后端崩了懒得起,又或者是觉得Github Pages很cool,总之一时心血来潮就迁移过来了。

Hexo是一个博客框架,可以生成静态页面并托管到Github上,用户可以用Html,Markown来编写文章。不用Jekyll的原因啊是因为要捣鼓Ruby的gem,而Hexo是运行在Node.js上的,装起来比较省事。

安装Hexo

身为一名前端开发,早已装好Git和Node.js了,如果没有其实Hexo的教程里都有步骤。
https://hexo.io/docs/

首先是安装Hexo

Mac下会有DTrace报错的问题,每次运行都会报错但是不影响使用。解决该问题,在安装hexo的时候加上 --no-optional 即可。
https://hexo.io/docs/troubleshooting.html#Error-with-DTrace-Mac-OS-X

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
$ sudo npm install -g hexo-cli
……
$ hexo init blog
INFO Cloning hexo-starter to ~/Documents/nodejs/blog
……
INFO Install dependencies
……
> node install
……
INFO Start blogging with Hexo!
$ cd blog
//解决Mac下DTrace错误,需要补刀
$ npm install hexo --no-optional
……
$ hexo
Usage: hexo <command>
Commands:
clean Removed generated files and cache.
config Get or set configurations.
deploy Deploy your website.
generate Generate static files.
help Get help on a command.
init Create a new Hexo folder.
list List the information of the site
migrate Migrate your site from other system to Hexo.
new Create a new post.
publish Moves a draft post from _drafts to _posts folder.
render Render files with renderer plugins.
server Start the server.
version Display version information.
Global Options:
--config Specify config file instead of using _config.yml
--cwd Specify the CWD
--debug Display all verbose messages in the terminal
--draft Display draft posts
--safe Disable all plugins and scripts
--silent Hide output on console
For more help, you can use 'hexo help [command]' for the detailed information
or you can check the docs: http://hexo.io/docs/
$ ls
_config.yml package.json source
node_modules scaffolds themes

这样就生成了一个名为blog的目录,里面有以下文件

_config.yml

配置文件

package.json

项目描述文件

scaffolds

脚手架目录,里面是模板文件,要写一篇新文章的时候,会以scaffolds里的模板生成新文章。

source

源文件目录,_posts文件夹里放着文章,除此之外以_为前缀的文件夹都会被忽略。所有的页面最终会渲染在public目录下。

themes

主题目录,渲染出静态页面的时候会把source里的页面(文章)套用这里的主题。

配置Hexo

编辑_config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Site
title: JS工作室
author: j3l11234
language: zh-CN
timezone: Asia/Shanghai
# URL
url: http://blog.j3l11234.com
root: /
#Writing
new_post_name: :year-:month-:day-:title.md
# Deployment
deploy:
type: git
repo: https://github.com/j3l11234/j3l11234.github.io.git
branch: master

new_post_name 是source/_posts里文章的命名格式,笔者习惯以日期作为前缀,这样好排序。
deploy里的repo根据实际情况填写,使用git做提交的话,需要额外安装一个包
npm install --save hexo-deployer-git

运行Hexo

生成的项目里,已经有source/_posts/hello-world.md一篇文章作为示例了。这时可以运行看看效果。

1
2
3
4
5
$ hexo server
INFO Start processing
INFO Hexo is running at http://localhost:4000/. Press Ctrl+C to stop.
//其实运行 hexo s 就可以

https://hexo.io/docs/server.html 有详细的介绍,比如指定端口和ip什么的。

这时候打开http://localhost:4000/就可以看到效果了。如果这时候修改source下的文件,直接刷新页面就可以看到修改。

创建新文章

直接创建一篇的新的文章。post可以省略,因为_config.yml里配置了default_layout: post

1
2
$ hexo new post test1
INFO Created: ~/Documents/nodejs/blog/source/_posts/2017-02-24-test1.md

也可以先创建草稿,编写完成后再publish。

1
2
3
4
5
$ hexo new draft test2
INFO Created: ~/Documents/nodejs/blog/source/_drafts/test2.md
$ hexo publish test2
INFO Published: ~/Documents/nodejs/blog/source/_posts/2017-02-24-test2.md

从ghost迁移到hexo

标准方法

从ghost里导出得到source.json,放在blog目录下。

修改 scaffolds/post.md文件,添加tag

1
2
3
4
5
---
title: {{ title }}
date: {{ date }}
tags: {{ tags }}
---

1
2
$ npm install hexo-migrator-ghost
hexo migrate ghost source.json

旁门左道

当时手头只有一个ghost.db,也就是ghost的数据库,在懒得装ghost的情况下,手动去读取并生成文件。
各位看看就好,请勿模仿。

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
var sqlite3 = require('sqlite3');
sqlite3.verbose();
var fs = require('fs');
Date.prototype.Format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
function item2File(row) {
var fileName = new Date(row.created_at).Format("yyyy-MM-dd") + "-" + row.slug +".md" ;
var content = "\
---\n\
title: "+row.title+"\n\
date: "+new Date(row.created_at).Format("yyyy-MM-dd hh:mm:ss")+"\n\
updated: "+new Date(row.updated_at).Format("yyyy-MM-dd hh:mm:ss")+"\n\
tags:\n\
---\n"+row.markdown;
//console.log(content);
fs.appendFile("./source/_posts/"+fileName, content, function(err){
if(err)
console.log("fail " + err);
else
console.log(fileName);
console.log("created the post file");
});
}
var db = new sqlite3.Database("ghost.db", sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,
function(err) {
if (err) {
console.err('FAIL on open database ' + err);
process.exit(-1);
}
});
db.each("SELECT title,slug,markdown,created_at,updated_at,published_at FROM posts", [],function(err, row) {
if (err) {
console.err('FAIL on select database ' + err);
}
//时间修正
if (row.published_at && row.created_at > row.published_at)
row.created_at = row.published_at;
if (row.published_at && row.updated_at > row.published_at)
row.updated_at = row.published_at;
item2File(row);
});

部署

为了迎合Github Pages的自定义域名,我们新建source/CNAME,里面写上域名

1
blog.j3l11234.com

这样在push到github之后就不需要在手动设置自定义域名了。如果你使用xxxxx.giuhub.io这样的原生域名,可以忽略该步骤。

然后是生成页面并部署

1
2
3
4
5
6
7
$ hexo generate
INFO Start processing
INFO Files loaded in 266 ms
INFO Generated: index.html
……
INFO 28 files generated in 1.05 s
$ hexo deploy

配置多说评论

按照教程可以很简单的弄完。
http://dev.duoshuo.com/threads/541d3b2b40b5abcd2e4df0e9

有一个小坑,_config.yml里边的duoshuo_shortname:,指的是你在多说的域名,比如我的是j3l11234.duoshuo.com ,那么就应该这么填

1
2
#DuoShuo
duoshuo_shortname: j3l11234

我建议将data-thread-key="<%= post.layout %>-<%= post.slug %>"改为data-thread-key="<%= post.slug %>",把slug作为多说文章的key,这样从ghost迁移之后,原来文章的评论也可以一起同步过来。

1
2
3
<!-- 多说评论框 start -->
<div class="ds-thread" data-thread-key="<%= post.layout %>-<%= post.slug %>" data-title="<%= post.title %>" data-url="<%= page.permalink %>"></div>
<!-- 多说评论框 end -->

sitemap

运行以下命令,安装hexo-generator-sitema

1
npm install hexo-generator-sitemap --save

打开根目录下的_config.yml文件,添加如下代码:

1
2
sitemap:
path: sitemap.xml

参考 https://github.com/hexojs/hexo-generator-sitemap

keywords

打开根目录下的_config.yml文件,添加如下代码:

1
2
3
4
5
6
# Site
title: JS工作室
author: j3l11234
language: zh-CN
timezone: Asia/Shanghai
keywords: j3l11234,HTML5,JavaScript,React

打开/Users/j3l11234/Documents/nodejs/blog/themes/landscape/layout/_partial/head.ejslandscape是默认主题名称,添加如下代码:

1
2
3
4
5
<% if (page.keywords){ %>
<meta name="keywords" content="<%= page.keywords %>,<%= config.keywords %>">
<% } else if (config.keywords){ %>
<meta name="keywords" content="<%= config.keywords %>">
<%} %>

如果页面有关键字,则用页面的关键字和配置的关键字,否则只使用配置的关键字。

在文章里面加入keywords:

1
2
3
4
5
6
7
---
title: 从Ghost迁移到Hexo
date: 2017-02-24 09:46:31
categories:
tags:
keywords: Ghost,Hexo
---

参考 https://segmentfault.com/a/1190000007477815

总结

Hexo用起来还是很畅快淋漓的,渲染出静态页面之后,爱放哪放哪。感觉很Geek,很符合『轻博客』的原则。