↔️

Hugoでタグ別ページで次のタグ/前のタグのリンクを表示する

2024/01/31に公開

背景

  • Hugo を使っているとタグ別ページを簡単に作成できる (/tag/foo, /tag/bar, …のような調子)
  • 個別のタグ別ページから他のタグ別ページへのリンクを貼りたい
  • タグをアルファベット順でソートしておいて, そのときの前のタグ, 後のタグをリンクできるといい塩梅
  • Hugo には Page Methods として NextInSection が提供されているが, タグ別ページだとこれは機能しない様子
  • 検索しても簡潔に実現できる方法がなさそうだったので, 自前で実装する

方法

コード

term page template (term.html など) で次のようなコードを追加する:

<nav>
    {{ $taxonomyObject := .Site.Taxonomies.tag }}
    {{ $currentTerm := .Title }}
    {{ range $i, $term := $taxonomyObject.Alphabetical }}
        {{ if eq $currentTerm $term.Term }}
            {{ if gt $i 0 }}
                {{ $.Scratch.Set "prevTerm" (index $taxonomyObject.Alphabetical (sub $i 1)).Page }}
            {{ end }}
            {{ if lt (add $i 1) (len $taxonomyObject.Alphabetical) }}
                {{ $.Scratch.Set "nextTerm" (index $taxonomyObject.Alphabetical (add $i 1)).Page }}
            {{ end }}
        {{ end }}
    {{ end }}
    <span>
        {{ with index .Scratch.Values "prevTerm" }}
            <a href="{{ .RelPermalink }}" rel="prev">Prev: {{ .LinkTitle }}</a>
        {{ end }}
    </span>
    <span>
        {{ with index .Scratch.Values "nextTerm" }}
            <a href="{{ .RelPermalink }}" rel="next">Next: {{ .LinkTitle }}</a>
        {{ end }}
    </span>
</nav>

簡単な解説

  • .Site.Taxonomies.tag を使って Taxonomy object を取得: Taxonomy variables | Hugo
    • .Site.Taxonomies.tag.tag は使用する taxonomy に合わせて適宜置き換える (.genres.categories とか)
  • $taxonomyObject は単なる map らしい (print デバッグで中身を確認できる)
  • $currentTerm := .Title で現在のページの term を取得 (もっと正当な方法がある気がする)
  • $taxonomyObject.Alphabetical でアルファベット順にソート
  • ループの中身は単に「現在のページの term に一致したら前後のページの Page 変数を記録」という処理
  • $.Scratch.Set "prevTerm" ~ でループ中の結果を記録
  • ループを抜けたら記録した結果を取り出してリンクを追加

補足情報

  • term page template とは: Template lookup order | Hugo
  • Q. .Scratch とは? A. いい感じに情報を記録できる場所. ループの外で事前に変数宣言しておいてそこに記録という方法でもいけるかもしれない
  • $. は global context へのアクセス: Templating | Hugo

References

Discussion