よつまお

過去ログ倉庫を兼ねたライフログ的な雑記ブログ。記事ジャンルにこだわることなく、不定期更新でゆるゆる運営しています。

ブログ移転 ( https://www.yotsumao.org/ )

 

Hugoの記事の更新日管理でenableGitInfoを使ったらつまずいた件

古い記事の内容を逐一チェックしてアップデートするようなマメな性格じゃないので、記事の更新日時ってあんまり気にしたことないし、

ええぃしゃらくせぇ!とさえ思うんだが、それにしたって公開日だけしか書かれてないのもいよいよSEO的にアレかーと思い立ってカスタマイズ。

 

と、せっかく重い腰を上げたのに、思わぬところでつまずいて謎事象に出会ったのでメモ。

 

まず前提。Hugoでは基本的にfrontmatterに更新日時を記述していくことになる。

とはいえ、既にアップしている記事すべてに一つ一つ追記していくなんていうすさまじい手間をHugoの開発者たちは許さないので、超絶便利機能が存在している。

 

config.tomlをさくっと開き、颯爽と

[frontmatter]
  lastmod = [":fileModTime"]

を追記するだけで、ファイルのタイムスタンプがそのまま更新日時になる。

 

とはいえ、Hugoでサイトを公開しているなら、まず当然にGitでコミットしているので、どうせなら更新日時だってGitのコミット日時を流用して管理したいはず。

 

というわけで、その場合は、

enableGitInfo = true
[frontmatter]
  lastmod = ":git"

とすることで、あっという間に全記事の更新日時の設定が可能になる。

 

ちなみに。lastmodに定義する日時は複数指定しておくと安全。

[frontmatter]
  lastmod = ["lastmod", "date", "publishDate", ":git", ":fileModTime"]

この場合、フロントマターにlastmodが記述されていたらそれを更新日時として最優先表示、それがなければ順にdate、publishdate、

それら更新日時の記述が無いような記事の場合に、ようやくgitのコミット日時を使い、コミット前の記事にはファイルのタイムスタンプを使用する、という感じ。

 

また、例えばファイル名に日付を入れて管理しているような場合には、

[frontmatter]
  lastmod = [":filename"]

と記述することで、ファイル名を更新日時とすることも出来たりする。

※2001-01-01-hogehoge.mdというファイル名の更新日時は、2001年1月1日とすることができる。

 

さて、前置きが長かったが、ようやく本題。

enableGitInfo = true

たったこの一行を書くだけで、さくっとGitのコミット日時が取得できるはずだった。

(もちろん記事表示に反映させるためには、後述のようにテンプレートのhtmlファイルに.lastmod云々を追記するわけだが)

 

しかし現れた表示は、

Jan 1, 0001

である。しかも全記事がそれ。

 

当ブログのテーマ、ClarityではデフォルトでJan 1, 2001の表記なのでそれはいい。

問題は「0001」。なんだよ0001年て、AD1年かよ。

 

ググってみてもどうも解決に至らない。

GitHub Actionsでデプロイしているわけだが、例えばタイムゾーンの問題で更新日時がずれているなら

- name: Build
  run: TZ=Asia/Tokyo hugo --minify

として環境変数TZを設定すればいい。

 

しかし0001はズレてるってレベルじゃない。

 

また、更新日時が全て最新コミットの日時になってしまうのなら、

- uses: actions/checkout@v2
  with:
    submodules: true
    fetch-depth: 0

とfetch-depthを0にして、全履歴を取得できるようにすればいい。

 

だが、0001年にコミットしたことがあるはずがない。

 

この辺りでそろそろ、config.tomlのenableGitInfoが上手く効いてねんじゃね?と気づきはじめる。

 

なので、試しにもう一つの方法、ビルドオプションに--enableGitInfoを付けてビルドしてみる。

 

すると、あっさりいけた。

なにこれHugoのバグ?テーマのバグ?最新バージョン使ってなかったっけ?

と釈然としなかったのでググり続けると、ついに英語のフォーラムで同様の現象を発見。

 

ここで結論を言うと、

 All Hugo config variables need to be before anything [foo].

Hugoの設定変数は全部[hogehoge]の前に書けよバーロォ、という話だ。

 

おそるおそる当サイトのconfig.toml、enableGitInfo = trueの上の行を見てみると、

[taxonomies]
# category = "categories"
  tag = "tags"
# series = "series"

ありやがった。[foo]が。ごく自然にtomlファイルの最終行に追記してたので完全ノーマークだった。

 

というわけで、例えば上の例だと、

enableGitInfo = true

[taxonomies]
# category = "categories"
  tag = "tags"
# series = "series"

[frontmatter]
  lastmod = [":git"]

こう書けば、enableGitInfoが効く。

試しにビルドオプションを消してみても、gitの更新日時が正常に表示された。

 

ちなみに話。

先述の通り、これだけではGitのコミット日時を取得して更新日時にするよーというだけの定義であって、当然記事内に表示するためにはもうワンステップ必要になる。

 

大体single.htmlをいじっている例が多いが、

例えばClarityなら、post-meta.htmlがそれにあたる。

 

一例としては、

 {{- if $showDate }}
    <span>{{ partial "sprite" (dict "icon" "calendar") }}</span>
    <span class="post_date">
      <time itemprop="datePublished" datetime="{{ .Date }}">
{{ .Date.Format (default "Jan 2, 2006" $.Site.Params.dateFormat) -}}
    </time></span>
    {{- if ne .Date .Lastmod }}
    <span class="post_date_lastmod">
    <time itemprop="dateModified" datetime="{{ .Lastmod }}">
(Updated on Git: {{ .Lastmod.Format (default "Jan 2, 2006" $.Site.Params.dateFormat) -}})&nbsp;
     </time></span>
    {{- end -}}
    {{- $scratch.Set "writeSeparator" true }}
  {{- end }}

こんな感じの記述にすることで、記事の公開日時および更新日時を表示させることが出来る。

 

テーマによっていろいろとやり方が変わってたり、ワードプレス様に比べればまだまだ情報が少ないなのがHugoのつらいところよね。