博客迁移至 Hugo 并实现自动化
2019年10月20日 · 2105 字 · 5 分钟 · Hugo
好久不见!
自 6 月以来,本人虽然没什么产出,但怎奈没动力写博客,至今只写了两篇不疼不痒的综述文章。但今天(2019/10/20)偶然在 v2ex 上看到了 hexo 释出 4.0 版本 的消息,而后想到自己曾数次想要脱离贵前端生态圈,摆脱令人脑壳痛的依赖问题,实现博客自动化等等等等事情。
于是,我趁着今天是闲暇的周日,把一切事情办好了。
下面是过程复现与总结。
Hugo
其实最早我并不是太想换到 Hugo 的,但奈何自己想要写一个静态博客生成器的计划一直提不上日程…… 便选择了这个解决方案。
之后是主题的选择。由于 Hugo 的主题生态圈较之 Hexo 仍较为匮乏,因此选择并不多。经过我在各种网站上的搜罗与比较,下面列出我较为偏向的选择:
- Maupassant,这个是我在 Hexo 上一直使用的主题,但 Hugo 上的移植版我不太满意,pass。
- https://linw1995.com/,这个主题我十分喜欢,但由于没有提供主题的 repo,只能作罢。
- LeaveIt,这个主题看着还行,但太久没维护,都没办法用……
- KeepIt,这个是上面 LeaveIt 的 fork,也是我最终的选择。
但由于 KeepIt 的功能还是不太能满足我的需求,因此我又 fork 了一份,作为自用。地址 batkiz/left
开始迁移
整个迁移过程中,我最在意的是该死的 兼容性 ,即,我新生成的博客要与之前的博客在整体行为上没有太大变化,下面就是在保证兼容性前提下的迁移过程。
链接
之前的链接不能直接 404,让读者找不到文章(虽然原来就没啥读者),不能造成割裂行为。
Hexo 默认的链接生成方法为 /:year/:month/:day/:filename/
,而 Hugo 的则为 /:year/:filename/
。
解决很简单,修改为相同的即可。
RSS
之前在 hexo 之上构建时,我采用的 hexo 插件是生成出 atom.xml
文件的,而在新的主题下生成的则是 index.xml
。
解决方法:在 config.toml
中加入下列内容
[outputs]
home = ["Atom", "HTML"]
[outputFormats.Atom]
mediatype = "application/rss"
baseName = "atom"
即可生成 atom.xml
文件作为 RSS feed。
在成功解决上述兼容性问题之后,新问题随之而来:为什么生成的 xml 里 tmd 没有内容?
为解决此问题,我试着看了看源码,但看不懂(
接着我试了试 Google,感谢 kaushalmodi 的代码,我用它覆盖了 index.atom.xml
之后便成功部署了正确的 RSS,简单修改(将默认的只生成最近 6 条增加到 20)之后便符合了需求。
mathjax
虽然我平时很少输入数学公式,但这个功能也不能少!
首先我尝试了将 mathjax 的支持直接写入 head/footer/js 等几个模板,但,还是没用(即使我已经在源码中看到了 mathjax 的支持代码)。
接下来仍然是 Google。
感谢 匿蟒,我在 在 Hugo 中使用 MathJax 一文中找到了解决方案,即下述方法:
在添加 MathJax 时,把所有修改写成了一个 layouts/partials/mathjax.html
文件:
<script
type="text/javascript"
async
src="https://cdn.bootcss.com/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
>
MathJax.Hub.Config({
"HTML-CSS": {preferredFont: "TeX", availableFonts: ["STIX", "TeX"], linebreaks: { automatic: true }, EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50) },
tex2jax: {inlineMath: [["$", "$"], ["\\(", "\\)"]], processEscapes: true, ignoreClass: "tex2jax_ignore|dno", skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'] },
TeX: {noUndefined: { attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "90%"} }, Macros: { href: "{}" } },
messageStyle: "none"
});
MathJax.Hub.Queue(function () {
var all = MathJax.Hub.getAllJax(), i;
for (i = 0; i < all.length; i += 1) {
all[i].SourceElement().parentNode.className += 'has-jax';
}
});
</script>
<style>
code.has-jax {
font: inherit;
font-size: 100%;
background: inherit;
border: inherit;
color: #515151;
}
</style>
这里,把官网的三处修改合并成一个 partial。 此外,还把 MathJax 的 CDN 从 cdnjs.cloudflare.com
替换成了 cdn.bootcss.com
,更好地支持国内。
把这个 partial 模板添加到 <head>
中,即可正常工作。
{{partial "mathjax.html" .}}
frontmatter
Hugo 支持 toml, yml 与 json 格式的 frontmatter,但与 Hexo 的 yml frontmatter 又有所不同。
Hugo 中的 tags 的形式应为
tags:
- hello
- world
- etc
即使只有一个 tag ,也要按此格式来写,否则会编译错误。
此外还有 title 的值应被包裹在括号之中等。
另外,hexo 中的 time 项可不用修改,Hugo 似乎已支持了此种格式。
版本控制与自动化
很久之前也曾想过要实现博客的云同步与自动化部署,但当时没有余力去做,今天趁着迁移博客,顺带利用 GitHub actions 实现自动化。
版本控制
首先是对内容(markdown 文件)的版本控制。
对 hugo new site .
生成出来的文件夹,使用 git init
,并添加以下的 .gitignore
信息:
/archetypes/
/data/
/layouts/
/public/
/resources/
/static/
/themes/
这样的话,只有下面两项被加入了版本控制之中:
content/
,这个是文章所在的文件夹config.toml
,这个是 hugo 的配置文件
之后可以将此目录推向 GitHub,进行文章的版本控制与部署的自动化。
自动化
Hugo 的无依赖特性、配置都写在根目录下的 config.toml 文件中的功能与 GitHub Actions 的出现,使得文章自动部署变得极为简单。毫不夸张的说,在最初的配置之后,我们可以专注于文章的内容,本地甚至不需要有 Hugo 的存在。
下面是 GitHub Actions 的 workflow,详情请看注释。
name: blog
on: [push]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
# 使用预编译的 Hugo 二进制文件
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2.2.2
with:
hugo-version: "latest"
# 使用 Hugo-extended 版本
extended: true
# 新建站点
- name: new site
run: |
hugo new site $HOME/blog
# 获取主题
- name: get theme
run: |
git clone --depth=1 https://github.com/batkiz/left.git $HOME/blog/themes/left
# 获取 username.github.io 以保持 commit 记录
- name: get username.github.io
run: |
git clone --no-checkout https://github.com/batkiz/batkiz.github.io.git $HOME/blog/public
# 获取内容文件
- uses: actions/checkout@v1
with:
fetch-depth: 1
# 将内容文件复制进入站点内
- name: copy in
run: |
rm -rf $HOME/blog/config.toml $HOME/blog/content/
/bin/cp -rf config.toml $HOME/blog/config.toml
/bin/cp -rf content/ $HOME/blog/content/
# build
- name: build
run: |
cd $HOME/blog
HUGO_ENV=production hugo --gc --minify
# 将生成出的站点推向 username.github.io
- name: publish
env:
USER: batkiz
EMAIL: batkiz@outlook.com
GH_REF: github.com/batkiz/batkiz.github.io.git
# 这里的 token 需要自己在 GitHub settings 中部署,并利用 actions 的 secrets 功能
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
cd $HOME/blog/public
git config --global user.name $USER
git config --global user.email $EMAIL
git add .
git commit -m "Auto Update: `date +'%Y-%m-%d %H:%M:%S'`"
git push "https://$USER:$GH_TOKEN@$GH_REF" master:master
感谢 https://github.com/peaceiris/actions-hugo 提供的可在 GitHub actions 使用的 Hugo 二进制文件,避免了每次都手动编译 Hugo。
另外希望大家别不看内容就随便写,会出 typo 的,然后 failed(泪
结语
经过一个下午 + 一个晚上的努力,终于成功地把博客迁移到了 Hugo,并实现了内容的版本管理与自动化部署。可喜可贺,可喜可贺。
接下来大概会抽空将以前的文章格式调整一下(Hugo 的 markdown 不知道是用啥解析的,写的随意的话不会按你想的那样渲染),以及自己写一个 Hugo 的主题。
see you later.