前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hugo 与 Hexo 的异同

Hugo 与 Hexo 的异同

作者头像
莲花海
发布2020-01-21 10:54:41
4K0
发布2020-01-21 10:54:41
举报
hugo-vs-hexo.png
hugo-vs-hexo.png

前言

Hugo 是一个基于 Go 语言开发的静态网站生成器(SSG),目前由 @bep 领衔开发,Hugo 的突出特点是简洁、灵活、高效,目前有很多知名网站都在使用 Hugo:NetlifyLet’s EncryptIPFSCloudflare DevelopersDigitalOcean Docs1Password 等等。与目前国内流行的 Hexo 相比,Hugo 的速度可称为飞速?——在安装和使用上都是如此。

下面,我们就来看一下 Hugo 与 Hexo 的一些异同,不过需要注意的是:此文主要探讨的是用户层面上的一些异同,而非技术层面的差异。简体中文来说?:即一个技术小白(我)从 Hexo 迁移到 Hugo 时遇到的一些常见问题。

目录结构

1 2 3 4 5 6 7 8 9 10 11 12

~/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 主题举个例子(已剔除无关文件):

1 2 3 4 5 6 7

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

其中,assetsdatalayoutsstatic 的作用都是与站点目录下的相应文件夹相同的,且站点目录下的文件可以覆盖主题目录下的相应文件——这意味着你可以在不修改主题文件的前提下方便地定制主题。在 Hugo 中,如果你想要定制主题,你只需在站点目录下新建相应的文件即可。这是非常利于主题的维护的,你只需使用 Git 的 submodule 的方式安装 Hugo 的主题,然后更新时只需直接在站点根目录下敲一条命令回车即可,非常方便!同时,这在持续集成部署时也会方便很多,这点你可以在 GitHub 中看出来,如下图。

git-submodule.png
git-submodule.png

◎ 以子模块的方式安装主题

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

配置文件

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

分类方式和组织方式

实话实说,这应该是从 Hexo 迁移到 Hugo 中遇到的最难的问题了,主要是概念上很难转过来。我们知道,在 Hexo 中有两种分类方式——分类和标签,它们都是在文章的 Front Matter 中设置的,其中:categories 是具有顺序性和层次性的,即你可以通过它来实现树状结构的分类;tags 则没有这种特点,它的作用只是将不同的文章联系起来。由于 Hexo 中的 categories 具有这样的特点,因此在 Hexo 中 categories 可以作为一种文章的组织方式——在 Hexo 中你可以将 categories 用在文章的 URL 结构中。

[3]

hexo-permalinks.png
hexo-permalinks.png

◎ Hexo 中的 URL 结构配置

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

Hugo includes support for user-defined taxonomies to help you demonstrate logical relationships between content for the end users of your website. — https://gohugo.io/content-management/taxonomies/

简体中文来说?:「Hugo 支持用户定义的类别(taxonomies)来帮你为自己网站的读者展示文章之间的逻辑关系」。也就是说,在 Hugo 中其实你可以自定义自己想要的任何类别,而不仅限于部类(categories[4]和标签(tags),比如:你可以自定义一个 series,也就是系列╱专题╱专栏。

既然 Hugo 中基于 Front Matter 的部类和标签都属于类别,而类别的作用只是联系文章,部类自然不可能有树状结构,自然也不能用部类来组织文章。那么,在 Hugo 中你要怎么组织文章呢?分区(Sections)。所谓分区,即站点的 content 目录下的文件夹和子文件夹,一个文件夹即一个分区[5]。很明显,这是基于文件系统的结构的,自然也就支持树状╱网状╱嵌套结构,也就能够用来实现文章的树状分类。我觉得这是 Hugo 的又一个优点,直接利用起文件系统的结构来组织文章,合理且符合用户预期,Markdown 文档的存放也更有序。

URL

迁移博客过程中最重要的莫过于保证文章的 URL 不变,不然,这将会非常不利于 SEO。好不容易有一篇文章出现在 Google 相关搜索结果的前排,却因为 URL 的变化导致原链接 404 从而导致该文章从 Google 的索引中移除,这一定会是非常令人沮丧的?。

当你从 Hexo 迁移到 Hugo 时,如果你在 Hexo 中的站点配置文件 _config.ymlpermalink 中只使用了 :year:month:day:title 变量的话,那么文章的 URL 是能够平滑地迁移到 Hugo 的,见 URL Management。同时,提醒一点,Hexo 中的文章中的 Front Matter 中的 permalink 在 Hugo 中对应的是 slug

但是,对于某些用户(比如我)在迁移时则可能会有一些麻烦,比如在 Hexo 中使用了 :category:id:abbrlink 变量,以及 .html 后缀。下面就来讲讲这些情况的解决之道。

首先就是部类,即 Categories 页面,也即 Front Matter 中的 categories,也即配置文件里的 :category

正如上文所说的,Hugo 中的部类是与标签无差别的,所以在 Hugo 中你是无法实现多级的部类的,即当你从 Hexo 迁移到 Hugo 时,/categories/foo/bar/ 这样的链接是一定会 404 的,除非你使用 Aliases。当然,这其实也无所谓,因为重要的是文章的链接,其它页面的链接可保持也可不保持。

对于文章的链接,如果你设计了复杂的多级部类(树状分类)且将之加入了文章的 URL 结构,那么在 Hugo 中保持文章 URL 中的这种结构的合理方式就是使用分区 Sections,然后在 Hugo 的配置文件 config.toml 中的 permalinks 配置相应的分区的 :sections 变量[6]

然后是 .html 后缀,博主当时年轻,想着加上这个显得 COOL 一点,于是添加了此参数并随着那篇教程带偏了很多人。现在接触了 Hugo,博主知道了这样的 URL 其实是很丑的,所以也就不在 Hugo 中保持了。毕竟,现代的服务器都有类似的自动跳转,这意味着原链接并不会 404,故在 Hugo 中也没必要再去丑化 URL。

当然,如果你还是想在 Hugo 中保持文章的 URL 的 .html 后缀,也不是没有办法,利用 Hugo 配置中的 uglyURLsOutput Formats 的一个配置项 noUgly 即可实现。首先在配置文件 config.toml顶部加上 uglyURLs = true,然后继续添加以下代码:

1 2 3 4 5 6 7 8 9 10 11 12 13

[outputFormats.NoUglyHTML] mediaType = "text/html" noUgly = "true" [outputFormats.NoUglyRSS] mediaType = "application/rss+xml" noUgly = "true" [outputs] page = ["HTML"] home = ["HTML", "RSS"] section = ["NoUglyHTML", "NoUglyRSS"] taxonomyTerm = ["NoUglyHTML", "NoUglyRSS"] taxonomy = ["NoUglyHTML", "NoUglyRSS"]

这样就能实现仅文章的 URL 是有 .html 后缀的,但需要注意的是:这样是会产生一些 bugs 的——具体我就不再花时间叙述了——因此还是建议直接抛弃 .html 后缀。

迁移时另外一个比较重要的 URL 问题应该是中文部类和中文标签的英文别名问题,比如你添加了一个「树莓派」标签,但你不希望该标签的 URL 是 /tags/树莓派/,你希望它的 URL 是英文的 /tags/raspberry-pi/。在 Hexo 中你可以通过站点配置文件 _config.yml 中的 tag_map 来实现,但在 Hugo 中没有这样的功能,那在 Hugo 中应该怎么办呢?

首先,你需要在配置文件 config.toml 中配置下部类和标签的 URL 结构:

1 2 3

[permalinks] categories = "/categories/:slug/" tags = "/tags/:slug/"

然后,在你的站点根目录下的 content 文件夹内新建 tags 文件夹,并在它的里面新建一个 树莓派 文件夹,最后在该文件夹内新建一个 _index.md 文件,并加入:

1 2 3

+++ slug = "raspberry-pi" +++

这样就解决了 URL 内的中文标签的别名问题。但还有一种特殊情况,就是你添加的标签如果比较复杂[7],比如 Raspberry Pi(树莓派)。那么此时,你在 tags 文件夹内新建的文件夹的名字就不能是标签的名字本身,而必须是 Hugo「链接化」后的标签名,比如 raspberry-pi树莓派。然后,在上面添加了 slug 的基础上,再手动添加一行 title = "Raspberry Pi(树莓派)" 以修正标题。此外,如果你在配置文件 config.toml 中设置了 disablePathToLower,那么新建的文件夹的名字就应该是 Raspberry-Pi树莓派

这里再来说一说 URL 中的英文字符的大小写的问题。在 Hexo 中如果你添加一个 Raspberry Pi 标签,那么它的 URL 是 Raspberry-Pi,但在 Hugo 中它的 URL 会变成 raspberry-pi,即将大写字母处理成了使 URL 更美观的小写字母。这也意味着当你从 Hexo 迁移到 Hugo 时,你的一些包含大写字母的原链接会 404,如果你想避免这个情况,你可以在配置文件 config.toml顶部加上 disablePathToLower = true。但我还是不建议这样做,因为全小写的 URL 的确会更美观,即使这会导致原链接 404,但重要的是文章的链接,而非某一标签页面。

最后,对于以上方法,我只能保证在 MemE 主题中是正常工作的。此外,MemE 主题支持复杂的中文标签名,支持复杂的中文部类名,支持复杂的中文分区名。

对于分区,我推荐直接使用小写英文命名,然后通过新建相应的 _index.md 并添加 title 以修正标题。当然,如果你要用中文也可以,但建议用简单的中文名。然后,如果你想要使分区的 URL 却为英文,比如:你想使「系列」分区的 URL 为 /series/ 而非 /系列/,那么你需要先在「系列」文件夹下新建一个 _index.md 文件,然后加上以下内容:

1 2 3

+++ url = "series" +++

最后在配置文件 config.toml 中配置下该分区下的文章的 URL 结构,比如:

1 2

[permalinks] "系列" = "/series/:slug/"

对于从 Hexo 迁移到 Hugo 在 URL 上的其它情况,比如在 Hexo 中使用了 :id:abbrlink 变量,那么你可以通过 url 在文章的 Front Matter 中直接手动指定文章的 URL,以保持文章链接的不变。

当然,如果在迁移时你想重构博客文章的 URL 结构,那么可以利用 Hugo 的 Aliases 或 Netlify 的 Redirects[8] 来保证原链接不 404。根据我的测试,这两种方式是都可以平滑地实现链接的迁移的,即不会降低文章在 Google 搜索结果中的排名。

其它方面

在迁移时还会遇到一些小问题,比如:日期格式、修改时间、阅读更多、Hexo 的标签插件等等问题,下面来一一说明。

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

然后是文章的修改时间的问题。在 Hexo 中,会自动将文件的修改时间作为文章的修改时间,但在 Hugo 中不会。不过你可以自行配置[9],在配置文件 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 中你必须将空格删除,即 <!--more-->

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

1 2 3

+++ title = "标签" +++

在 Hexo 中,你每对文章进行一次修改,你就必须要在浏览器中手动刷新一下页面,如此才能看到最新的渲染结果?。但在 Hugo 中,只要有相关变化,Hugo 就会自动为你刷新页面。也就是说,你可以即时预览?!顺便安利一个有用的技巧,在配置文件上方添加 newContentEditor = "gedit"(修改 gedit 为你喜欢的编辑器名),就可以在每次 hugo new 新建文章后自动打开你喜欢的文本编辑器!

在 Hugo 中,与 hexo s 命令等同的是 hugo server,但由于默认的文章模板里面有 draft: true,故需加上 -D 参数以渲染草稿;与 hexo g 命令等同的是 hugo,用来生成 public 文件夹;与 hexo clean 类似的命令是 hugo --gc --cleanDestinationDir;在 Hugo 中可以直接使用 hugo --minify 压缩 HTML、JS、CSS 等文件;在 Hugo 中,没有 hexo d 一键部署 public 文件夹到 GitHub 的操作,你需要自己新建脚本,但我建议使用 Git 管理整个站点,然后上传整个站点到 GitHub 以通过持续集成的方式部署,而非用 Git 直接部署 public 生产版代码,因为这其实是非常可笑的——Git 是用来管理源码的。此外,关于 hugo 命令的更多参数,请见 Commands

最后,Hugo 默认是渲染到内存的,如果你有一些特殊情况要调试,比如 Service Worker,那么你可以通过使用 --renderToDisk 参数渲染到硬盘来实现调试。此外,如果你有一个厚重的 static 文件夹(比如有大量图片或视频),那么也可以使用该参数以渲染到硬盘。不然,Hugo 可能会吃光你的电脑内存?。


  1. 当然,你也可以将它拆分开来,见:https://gohugo.io/getting-started/configuration/
  2. 下文的 TOML 代码中的缩进仅为美观和提高代码的可读性。
  3. 来自:https://hexo.io/zh-cn/docs/permalinks.html
  4. 为了在中文上将 Categories 和 Taxonomies 与广义的分类区分开来,今后一例将 Categories 翻译为「部类」,将 Taxonomies 翻译为「类别」。
  5. 需注意的是子文件夹内必须有 _index.md,否则 Hugo 不会认为该子文件夹为一个分区,见:https://gohugo.io/content-management/sections/#nested-sections
  6. Hugo 默认的分区的 URL 结构 /:sections/:slug/ 就有 :sections 变量,但如果你要添加其它变量,则需添加它。
  7. 即有空格、标点符号,或其它特殊符号。
  8. 如果你的博客部署在 Netlify 上的话。
  9. 在 Hugo 中,你甚至可以配置 Git 的改动(commit)时间为文章的修改时间,即 :git
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 目录结构
  • 配置文件
  • 分类方式和组织方式
  • URL
  • 其它方面
相关产品与服务
持续集成
CODING 持续集成(CODING Continuous Integration,CODING-CI)全面兼容 Jenkins 的持续集成服务,支持 Java、Python、NodeJS 等所有主流语言,并且支持 Docker 镜像的构建。图形化编排,高配集群多 Job 并行构建全面提速您的构建任务。支持主流的 Git 代码仓库,包括 CODING 代码托管、GitHub、GitLab 等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档