実現したいこと

content/recipes/のように、レシピ記事だけを集めたセクションを追加したとする。他のセクションは記事タイトルだけの一覧で構わないが、レシピ記事の一覧では調理時間をひと目でわかるように表示したい。

layouts/section.htmlを直接編集すると全セクションの一覧表示に影響してしまうため、recipesセクションだけ見た目を変える方法を確認する。

Hugoのテンプレート探索順

Hugoはsectionページ(セクション配下の一覧ページ)のテンプレートを探す際、次の優先順位でファイルを探索する。

  1. layouts/recipes/section.html
  2. layouts/section.html

Template Lookup Order | Hugo にあるとおり、セクション名と一致するディレクトリにテンプレートがあればそちらが優先され、無ければlayouts直下のテンプレートにフォールバックする。

この仕組みを利用し、layouts/recipes/section.htmlを新規作成すれば、recipesセクションだけ専用テンプレートを適用できる。

実装

まず各レシピ記事のフロントマターに、調理時間を表すcooking_timeパラメータを追加する。

---
title: "架空のカレーレシピ"
cooking_time: 40
---

layouts/recipes/section.htmlを新規作成し、一覧にcooking_timeを表示するバッジを追加する。

{{ define "main" }}
<h1>{{ .Title }}</h1>
<ul class="recipe-list">
  {{ range .Pages }}
  <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <span class="cooking-time-badge">{{ .Params.cooking_time }}分</span>
  </li>
  {{ end }}
</ul>
{{ end }}

recipesディレクトリに対応するテンプレートを配置しただけであり、layouts/section.html側には一切手を加えていない。そのため他のセクション(例えばnotes)は従来どおりlayouts/section.htmlによる一覧表示のままとなる。

動作確認

最小構成のHugoサイトを用意し、recipesnotesの2セクションを作成してビルドを確認した。

content/
  recipes/
    curry/index.md    (cooking_time: 40)
  notes/
    memo/index.md
layouts/
  section.html
  recipes/
    section.html

hugoコマンドでビルドすると、recipesセクションの出力にはlayouts/recipes/section.htmlの内容が反映され、調理時間のバッジが表示された。

<h1>Recipes</h1>
<ul class="recipe-list">
  <li>
    <a href="https://example.com/recipes/curry/">架空のカレーレシピ</a>
    <span class="cooking-time-badge">40分</span>
  </li>
</ul>

一方notesセクションの出力はlayouts/section.htmlのままであり、専用テンプレートを配置していないセクションには影響がないことを確認できた。

<h1>Notes</h1>
<ul>
  <li>架空のメモ</li>
</ul>

まとめ

セクションごとに一覧表示を変えたい場合、layouts/section.htmlを分岐で複雑にする必要はない。layouts/<セクション名>/section.htmlを追加するだけで、そのセクションだけに専用テンプレートを適用できる。他のセクションへの影響も無いため、特定セクションのみ表示を変えたいケースに適した方法である。

セクションページは一覧表示だけでなく、配下に記事を置かなければ単一ページとしても利用できる。【Hugo】sectionページを使ってプライバシーポリシーページを作る を参照。