実現したいこと

ブログにプライバシーポリシーのような固定ページを追加したいとする。記事一覧は不要で、本文だけを表示したいが、タイトルや日付、TOCなど通常記事と同じ見た目には揃えたい。

content/privacy-policy.mdのような単一ファイルでも実現できるが、この方法だと記事カテゴリ(content/android/など)と扱いが異なり、将来関連ページを増やしたくなったときに構造を作り直す必要がある。本記事では、記事カテゴリと同じ「セクション」の仕組みに乗せてプライバシーポリシーページを作る方法を確認する。実際このブログのプライバシーポリシーページ もこの方法で作られている。

Hugoのsectionページとテンプレート

content/privacy-policy/_index.mdのように、ディレクトリ配下に_index.mdを置くとそのディレクトリはセクションとなり、ページの種類(kind)はsectionになる。

セクション名と一致するディレクトリ配下に専用テンプレートが無ければ、kindがsectionのページにはlayouts/section.htmlが適用される(【Hugo】特定セクションだけ独自のsection.htmlを適用する方法 を参照)。

例えば、次のように_index.mdの本文と配下記事の一覧を両方表示する構造にする。

{{ define "main" }}
<article class="detail-article">
  <header class="article-header">
    <h1 class="title">{{ .Title }}</h1>
    ...
  </header>

  {{ if .Params.toc }}
  <div class="toc">
    {{ .TableOfContents }}
  </div>
  {{ end }}

  <div class="article-body">{{ .Content }}</div>
</article>

<div class="articles">
    {{ $paginator := .Paginate .RegularPages }}
    {{ range $paginator.Pages }}
    <!-- 配下記事の一覧 -->
    {{ end }}
</div>
{{ end }}

androidawsのような通常のカテゴリセクションには_index.mdを置いていないため.Contentは空になり、実質的に配下記事の一覧だけが表示される(.Title_index.mdが無くてもHugoがセクション名から自動生成する)。反対に、_index.mdへ本文を書いて配下記事を置かなければ.RegularPagesが空になる。この場合article部分の本文だけが表示される単一ページとして機能する。

実装

content/privacy-policy/_index.mdにタイトルと本文を書く。

---
title: "プライバシーポリシー"
date: 2022-08-20T08:20:20+09:00
toc: true
---

## 個人情報の利用目的

...

privacy-policyディレクトリには_index.md以外のファイルを置いていないため、配下記事は存在しない。

動作確認

hugoコマンドでビルドし、public/privacy-policy/index.htmlを確認する。

<article class="detail-article">
  <header class="article-header">
    <h1 class="title">プライバシーポリシー</h1>
    ...
  </header>
  <div class="toc">...</div>
  <div class="article-body">
    <h2 id="個人情報の利用目的">個人情報の利用目的</h2>
    <p>...</p>
    ...
  </div>
</article>

<div class="articles"></div>

_index.mdの本文がarticle-bodyに展開され、配下記事が無いためarticlesは空のまま出力される。通常記事と同じヘッダーやTOCを備えつつ、一覧を持たない単一ページとして表示できている。

なお、実際のページをブラウザで開くと本文の下にも記事の一覧が表示されるが、これはsection.htmlarticlesではなく、サイドバーに表示される「LATESTS」(サイト全体の最新記事を集めた一覧)である。article要素の中身だけを見れば、プライバシーポリシーの本文以外は含まれていない。

まとめ

Hugoのセクションページは、_index.mdの配下に記事が無ければ、一覧を持たない単一ページとしても機能する。記事カテゴリと同じ仕組みに乗せられるため、既存のテンプレートやスタイルをそのまま流用でき、プライバシーポリシーのような固定ページを作るのに適している。