从 2018 年开始用 org-static-blog 写博客到现在也有几年时间了,写的文章比较少,总体上这个简单的静态网站生成方案都能够满足需求。
但中途也发现一些不够用的地方,比如之前想要并贡献了一个生成 meta description 的 PR ,以便更好地在搜索引擎展示结果( SEO );又比如中途一度有区分中英双语博客的需求( index 列表、 RSS 等),但苦于没有想到很好的方法,就只能把两种文章都混杂在一起展示,但这样用户的阅读体验不好;另外之前的样式也差强人意,比如主页的链接带下划线,不利于阅读。
最近又有了一些其他的需求,就考虑做一个升级方案,大致需求有:
- 内置支持 orgmode
- 支持中英双语
- 较完善的 SEO 支持
- 较完善的社交分享功能
- 能集中展示个人的其他社交网站链接
- 除了博客之外,还能够展示其他的内容
- 界面稍微美观一点
详细分析需求之后,需要考虑的因素有:
- [X] 保持 blog, tags, rss 链接不变
最重要的是 blog url 不能变,配置麻烦;最终决定 url 变了就变了,原来的 html 通过 meta refresh 来实现重定向解决。
- [X] SEO 功能验证
- [X] robots.txt
- [X] sitemap
- [X] 支持 description ( front matter 已内置支持)
- [X] front matter 支持文章更新时间
lastmod 字段
- [X] 社交分享效果验证
- [X] 选择一个合适的主题 theme
需要支持的特性( 综合考虑,最终选择 beautifulhugo ):
- [X] 需要 responsive
- [X] 多语言支持
- [X] 展示 social links
- [X] 社交分享支持
- [X] 首页文章倒序,最新的在最上面
- [X] 文章内部如何支持显示更新时间、其他语言版本?
不支持
- [X] 支持 toc 目录
暂不支持,但可以接受: https://github.com/halogenica/beautifulhugo/issues/219
- [X] 验证分页条数及效果
默认 10 条
根据 orgmode 官网 Blogs and Wikis with Org - orgmode.org 推荐,大致考察了几种方案:
- Jekyll 不支持 orgmode ,仅支持 Markdown ;采用 Ruby 编写的,不太熟悉;
- Hexo 不支持 orgmode ;采用 Node.js 编写,庞大的依赖让人望而却步;
- Hugo 采用 Golang 编写,只有一个二进制文件,安装简单;另外构建极快;
最终决定采用 Hugo ,本以为很快能搞定,结果没想到要正确配置 Hugo 并没有那么简单。
迁移过程及遇到的问题
第一次使用没有经验,一开始按照官方文档 Quick Start | Hugo - gohugo.io ,先 hugo new site hello-world
创建一个项目来玩玩,然后修改主题 theme = "ananke"
,并新建一个 post 然后 hugo server -D
启动开发版 web server 。
到目前为止,整个过程都很顺滑,编译速度非常快,只要 100+ms ,很让人惊艳。
用 Git 保存好当前的 config.toml
,继续尝试。
然后按照文档指引,根据多语言的设置配置,结果发现 ananke 并不能很好地支持多语言(如果没记错的话,它不支持目录结构的多语言模式),于是不得不换别的主题尝试。
结果发现换一个主题之后,原来 ananke 主题下的 config.toml
在新主题下却不能工作了。
回顾整个过程,遇到的主要问题主要有2个:
- 多语言目录结构是怎样的?
- 如何调整一个主题的设置?
一开始以为 Hugo 主题只负责 UI 的渲染,与 Hugo 核心没有太多耦合的东西,一个 config.toml
就能够轻松适配多种不同的主题。结果在更换主题的过程中发现并不是这样的,而且我发现每一种主题一般都有一个样例配置 exampleSite/config.toml
,这才渐渐明白 Hugo 的配置其实是以主题配置为中心,从主题附带的示例配置出发进行微调,整个过程会顺利很多。
接下来主要说说多语言的目录结构问题。
多语言的目录结构
关于多语言的设置,文档有一页 Multilingual Mode | Hugo - gohugo.io 专门细说。主要有两种方式:
- 同一个文件夹下,以不同的文件名“后缀”表示比如的语言,比如
hello-hugo.en.md
hello-hugo.zh-cn.md
分别表示同一篇文章的英文和中文版本。 -
通过不同文件夹来区分,比如一个
en
文件夹专门放英文文章,另外一个zh-cn
专门放中文文章。 官方文档给出的示例是这样的:/content/english/about.md /content/french/about.md
我比较倾向于第二种方式,这样文件归类比较清晰明了。
但是,事与愿违,偏偏在选主题的过程中发现很多主题都能够支持第一种方式,但是不支持第二种方式。
而且要命的是,对于第二种方式的目录结构,文档也没有明确的说明,导致我一直没有弄明白正确的目录结构。
比如配置这样设置 contentDir :
[languages]
[languages.en]
contentDir = "content/en"
languageName = "English"
weight = 1
[languages.zh-cn]
contentDir = "content/zh-cn"
languageName = "简体中文"
weight = 2
最初我以为配置要求的目录结构是这样的:
content/
posts/
en/
zh/
但通过摸索实践,最终发现它其实要求这样的:
content/
en/
posts/
zh/
posts/
这里发现的过程还挺有意思的,算是一种探索、发现新知识的手段。在经历了各种搜索都找不到结果,以及查看文档都始终不得要领的情况下,我就想,如何验证目录结构呢?
要不试试新建一篇文章,看它放在哪里了?
$ hugo new posts/test.org
/path/to/hello-world/content/posts/en/posts/test.org created
通过琢磨这里新建文件的路径,我终于明白了多语言的目录结构,如上边所说,其实就是每种语言目录都是一个新的根目录,当时还特意发了一条推文宣布这个发现:
@GoHugoIO 's config of multilingual mode is tricky, the correct directory hierarchy is like picture #2, instead of picture #3.
— whatacold (@whatacold) July 6, 2021
Don't ask me how I figured it out, at last...😩😩 pic.twitter.com/9evBfsvH7s
网站最终效果
经过对原来 org-static-blog 的 orgmode 源文件进行了一些微整,以及对 beautifulhugo 主题的修饰之后,终于生成了现在这个比较满意的效果。
对于 orgmode 源文件的调整,有以下微调:
- date tags 这两个 front matter 格式调整
- 图片路径更改
-
博文的 URL 调整
由于博客访问量并不大,我可以接受 URL 变更,同时对于原有的 html 通过 meta tag 来实现类似的 301 重定向,比如这样:
<!DOCTYPE html> <html> <head> <meta http-equiv="refresh" content="0; url=/zh-cn/blog/2021-02-27-wrk-yuanli/"> </head> <body> <p>The page has moved to: <a href="/zh-cn/blog/2021-02-27-wrk-yuanli/">here</a></p> </body> </html>
对于 beautifulhugo 主题,主要参考 Keep Coding - liujiacai.net 的网站进行了配色调整,更加便于阅读。(具体做法是,拷贝一份 beatifulhugo 仓库中的 main.css 到自己工程 static/css/main.css
,然后再进行修改微调。)
遗留问题
虽然现在网站结果总体比较满意,但还存在一些小问题:
- 每一级 heading 使用编号,便于阅读
-
beautifulhugo 页面性能较差,打开一个网页会发起 30+ 请求
-
本地预览版本也会启用 Google Analytics ,污染数据有两种解决方法:
- 维护两份配置,本地预览和部署版本通过
--config <xxx.toml>
来区分,也可以同时传入多个配置文件,通过,
逗号隔开 -
以目录组织配置文件,通过命令行参数
--production
来指定环境;环境名就是 config/ 内的子目录名,_default/
目录放兜底的全量配置。比如这样的目录结构:
$ tree config/ config/ ├── _default │ └── config.toml # 全量配置,不配置 GA id └── production └── config.toml # 配置 GA id 2 directories, 2 files
第二种方法比较符合我的胃口,配置结构清晰,较为易用。有了上面的配置结构,通过
hugo server -D
启动的本地版本就不再上报 GA ;修改博客达到满意的效果之后,再hugo --environment production
生成最终的包含 GA 的网站。参考:
- 维护两份配置,本地预览和部署版本通过
favicon 在 Chrome 浏览器中无法显示,在 Firefox 中正常(本地开发环境都 ok )可能是特定浏览器版本的原因,现在也 ok 了。footer 中的版权年份展示不对,按道理应该要展示到 2021 年(突然又好了,不知道为何) 文档说明在 https://gohugo.io/variables/site/figcaption (图题)样式的辨识读很差(已解决)
Hugo 使用感受
Hugo 优点:很快,基本能满足我的大部分需求。
不足之处:
-
文档看起来很全,但是新手却很难快速地找到信息; 比如:
- 多语言的目录结构
- 配置文件参数有点乱,比如
[params]
vs.[Params]
齐飞(第一个字母大小写无关?),比如[Params]
参数存在的意义(或者说为何要定义这么一节配置)?
- 配置
config.toml
与主题强相关,换一个主题基本要重新配置,这点在文档中也没提到; 根据这几天的经验,我的最佳实践是,从选定主题的仓库中 copy 一个初始的 exampleSite 配置,然后再慢慢微调。
Hugo 不支持的 orgmode 特性
从目前遇到的情况看,发现不支持的 orgmode 特性有两个:
include
指令- 不支持 Evaluating Code Blocks