修正 Hugo 文章的最后修改时间

发表于 更新于

前言

Hugo 文章的修改时间生成有多种方案,部分方案无法自动化设置,部分方案又依赖 Git 信息。如果你这二者都不满足,本文将会告诉你如何在通用的 CI 环境中基于文件修改时间(mtime)来生成正确的文章修改时间。

以下内容基于这个 hugo.toml 设置片段:

[frontmatter]
  lastmod = [':fileModTime']

恢复文件修改时间

当我们的 CI 系统在克隆 Git 仓库时,文件的修改时间并不会被还原。因为 Git 不保存修改时间,且总是将修改时间设置为克隆时的当前时间。我们必须从其它 Git 信息中还原修改时间,否则生成的文章最后修改时间必然是错误的。

为什么好像又依赖 Git 信息了?主要是因为我们还在克隆代码这一步骤中,此时并不执行生成任务。

下载 git-restore-mtime 到仓库中,我们将在 CI 环境中执行它。这是一个 Python 脚本,它通过 Git 提交信息中包含的时间一键还原文件们各自的修改时间。

例如这是我的博客 CI 配置中的相关步骤:

steps:
  git-restore-mtime:
    image: alpine/git
    commands:
      - apk add python3
      - .ci/git-restore-mtime # <- 我将此脚本放在 .ci 目录中
这段是 Woodpecker CI 的配置,能看出含义就好。

Git 提交信息使用 UTC 时间,这个脚本会帮我们还原为本地时间。所以还原时我们不用在意时区。

构建环境添加时区

从上一个步骤中,我们还原了文件的最后修改时间。但仍然不够,因为通常 CI 环境默认是 UTC 时间,这会导致文章的修改时间仍然偏差了一个本地时区。

这个其实更好解决,我们在构建环境中添加时区信息即可:

steps:
  # 省略其它步骤……
  hugo-build:
    image: hugomods/hugo:reg-exts
    environment:
      TZ: Asia/Shanghai
    commands:
      - apk add tzdata
      # 省略其它构建命令……
      - hugo

我们给构建的系统环境添加 TZ 变量,并安装 tzdata 这个包(通常是必要的)。

至此生成的所有模板中的 .LastMod 字段值,皆为正确的修改时间。它对应文件的修改时间,而文件的修改时间对应 Git 提交历史中该文件的最后编辑时间。一切都是合理的。

在生成阶段,我们并未依赖 Git 信息。这在某些时候是有用的。

正确渲染修改时间

对于在意 SEO 的网站,我通常将时间放在 time 标签中。因为 time 标签提供了 datetime 属性,这个属性具有规范的值,可以让爬虫正确的解读时间。否则标签文本中各种非主流的为人类可读而构造的时间格式,爬虫难以理解。

这是一个例子:

{{ $datetimeFormat := "2006-01-02T15:04:05-07:00" }}
{{ $datetimeDisplay := "2006/01/02" }}

<time datetime="{{ .Lastmod | time.Format $datetimeFormat }}">
  {{ .Lastmod | time.Format $datetimeDisplay }}
</time>

上面的模板让我们的文章时间以 2024/04/27 的简单日期形式显示,但又提供精确具体的符合 ISO 8601 规范的时间值,如 2024-04-27T03:25:22+08:00

结束语

通常来讲,你不需要过于在意时间字段,因为搜索引擎会参考 sitemap.xml 中的结构化时间数据来判断内容修改时间。但如果你是一个完美的强迫症用户,你可能需要在这个过程中去深究。

本文由作者按照 CC BY 4.0 进行授权
分享:

相关文章