Go Hugo!

The world’s fastest framework for building websites

hugo-logo-wide◎ Hugo

在 2020 年的春节前夕,我终于完成了博客从 Hexo 到 Hugo 的迁移。期间踩过不少坑,也有不少小朋友来问我如何开始进行个人博客写作,因此觉着是时候写点东西记录记录。

#Why Hugo

正式开始写个人博客,是两年前的春节。最开始使用了当时最流行的 Hexo 框架,选择了 Next 主题。最开始一切都很好,虽然 Hexo 框架是简单了点,但耐不住有很多热心的开发者开发了很多插件,所以基本上都能满足自己的需求。而随着博客数量越来越多,我发现 Hexo 的问题越来越让我难以忍受,那就是:速度太慢。

举个例子,当我有 200 多篇博客的时候,用 Hexo 渲染静态网页需要将近 20 秒,这样的速度简直是不可接受的。更不要说我还有大量的静态图片、资料等等。同时,由于自己偷懒,博客中使用的图片都来自于图床,这些外链不受我控制,很多时候有打不开、加载慢的问题,让我这个强迫症觉得很不爽。

因此2019年底,我萌发了重构个人博客的想法,一眼就看中了用 Go 语言写的 Hugo,其Slogan The world’s fastest framework for building websites也是非常吸引我。更难能可贵的是,Hugo 虽然还处于快速迭代开发的阶段,但并不是一个半成品,很多在 Hexo 上需要插件实现的功能,Hugo 上都内置了。

#Hugo vs Hexo

为了方便 Hexo 用户快速上手 Hugo,我总结了 Hugo 与 Hexo 的异同点(大部分来源于官网及这篇博文)。

#结构组织

~/blog $ tree -L 1
.                     # 说明             Hexo
├── archetypes/     # 文章模板          scaffolds/
├── assets/         # Hugo 管道
├── config.toml     # 配置文件          _config.yml
├── content/        # 文章目录          source/_posts/
├── data/           # Hugo 数据文件     source/_data/
├── layouts/        # 布局模板
├── public/         # 生成的静态文件     public/
├── resources/      # Hugo 缓存
├── static/         # 网站的静态文件     source/
└── themes/         # 主题目录          themes/

在 Hugo 中,与 Hexo 的一个很大不同:是主题目录与站点目录有一样的结构,以 MemE 主题举个例子:

~/blog/themes/meme $ tree -L 1
.
├── assets/
├── data/
├── i18n/
├── layouts/
└── static/

其中,assets、data、layouts、static 的作用都是与站点目录下的相应文件夹相同的,且站点目录下的文件可以覆盖主题目录下的相应文件——这意味着你可以在不修改主题文件的前提下方便地定制主题。

在 Hugo 中,如果你想要定制主题,你只需在站点目录下新建相应的文件即可。这是非常利于主题的维护的,你只需使用 Git 的 submodule 的方式安装 Hugo 的主题,然后更新时只需直接在站点根目录下敲一条命令回车即可,非常方便。

此外,上面的 i18n 文件夹相当于 Hexo 的主题中的 languages 文件夹,如果你不喜欢主题的一些文字翻译,可以在站点目录下新建相应文件自定义。这里特别需要提醒的是,Hugo 中的 data 和 i18n 文件夹下的所有文件都是可以按「键」覆盖的,即你无需复制文件全文,只需添加你想自定义的那项即可。

#配置文件

Hugo 中是不区分站点和主题的配置文件的,Hugo 中只有一个位于站点根目录下的 config.toml 配置文件。你可能注意到 .toml 后缀,没错,Hugo 默认使用的配置文件是 TOML 格式的,它的语法是非常简单易懂的,它在语法上也没有缩进的要求。当然,在 Hugo 中你也可使用 Hexo 默认的 YAML 格式,但我还是建议你使用 TOML,毕竟入乡随俗嘛。此外,如果你想将文章中的 Front Matter 也从 YAML 转换成 TOML 的话,推荐一个 Python 脚本。但特别注意:尝试前务必先备份!

#分类方式

我们知道,在 Hexo 中有两种分类方式——分类和标签,它们都是在文章的 Front Matter 中设置的,其中:categories 是具有顺序性和层次性的,即你可以通过它来实现树状结构的分类;tags 则没有这种特点,它的作用只是将不同的文章联系起来。由于 Hexo 中的 categories 具有这样的特点,因此在 Hexo 中 categories 可以作为一种文章的组织方式——在 Hexo 中你可以将 categories 用在文章的 URL 结构中。

但是在 Hugo 中这是无法实现的,在 Hugo 中你是无法将文章的 Front Matter 中的 categories 用于文章的 URL 的。为什么呢?因为 Hugo 中的 categories 与 tags 在功能上其实是完全相同的,它们的作用都是将不同的文章联系起来。其实,Front Matter 中的 categories 和 tags 在 Hugo 中都属于 Taxonomies。

那么,在 Hugo 中你要怎么组织文章呢?分区(Sections)。所谓分区,即站点的 content 目录下的文件夹和子文件夹,一个文件夹即一个分区。很明显,这是基于文件系统的结构的,自然也就支持树状╱网状╱嵌套结构,也就能够用来实现文章的树状分类。

我认为这是一个非常好的设计,在使用Hexo时,博客数量一多,在本地的文件系统中就容易混乱,我还使用了一个插件,来自动将文件夹名字用于Front Matter中的 categories ,而在Hugo中直接就使用了这种分类方式。需要注意的是,如果有多级文件夹,需要在文件夹下新建_index.md使得其为新的categories。

#其它方面

首先是文章的 Front Matter 中的 date 日期格式的问题。在 Hugo 中,Hexo 默认的日期格式是不能工作的,比如:你必须要修改 1969-07-20 20:17:43 为 1969-07-20T20:17:43+00:00,即添加了时区的信息。对于这点,你可以用上文提到的那个 Python 脚本批量处理一下。

然后是文章的修改时间的问题。在 Hexo 中,会自动将文件的修改时间作为文章的修改时间,但在 Hugo 中不会。不过你可以自行配置,在配置文件 config.toml 中加入 :fileModTime:

1
2
[frontmatter]
    lastmod = ["lastmod", ":git", ":fileModTime", ":default"]

如此,就算你没有在文章的 Front Matter 中手动指定修改时间 lastmod,它依然会随着你的文章的改动或修改而「自动更新」。


在 Hexo 中,你可能会在 Markdown 中使用 Hexo 标签插件来实现一些 Markdown 语法无法实现的特殊排版需求。这些特殊的语法是无法在 Hugo 中生效的,尽管在 Hugo 中有与之对应的短代码,但它们之间的语法是不同的,故我建议最好放弃这种非 Markdown 原生语法的写法。当然,如果你非要手动将之从 Hexo 迁移到 Hugo 中也不是没有可能,比如:你可以用 hugo-notice 实现 NexT 主题的 Note 标签。

此外,对于文章摘要的截取,即「阅读更多」上方的内容。在 Hexo 中你可以在文章中加入<!-- more --> 来控来控制,但这在 Hugo 中是不会生效的,在 Hugo 中你必须将空格删除。

还有一个是 index.md 的问题,在 Hugo 中你必须在它的前面添加一个下划线,即 _index.md。比如:你想自定义标签页面的标题为中文,那么你先在新建一个 content/tags/_index.md 文件,然后在文件中加入:

1
2
3
+++
title = "标签"
+++

对于图片,我个人建议还是使用本地图片,而不是图床(血的教训)。在 Hugo 中,使用本地图片的方法很简单,直接在 static 文件夹中新建一个 images 子文件夹,然后在Markdown语法中使用:

1
![hugo-logo-wide](/images/misc/hugo-logo.svg "Hugo")

其中,最后的 Hugo 是图片的描述。

#Hugo theme

Hugo 是一个很活跃的社区,有非常多的主题可供选择。我目前的主题选择的是 MemE,开发者非常活跃且乐于接受 PR,同时审美在线,速度非常快,我非常满意。

开发者 reuixiy 有详细的主题开发介绍,我这里就不赘述了。

由于 MemE主题使用了大量 SVG 图片来加快加载速度(包括品牌栏、图标等等),我使用了 Inkscape 来制作了自己的品牌栏(还不错吧?),可供大家参考。


下一篇博客我会介绍,如何使用 Hugo 进行持续集成写作,同时同步到个人服务器中。

Load Comments?