【Hugo】Taxonomy を使わずに年月別アーカイブページを作る

投稿日:

カテゴリ:Web 制作

以前使っていた Blogger では、/[yyyy]/ で年別、/[yyyy]/[MM]/ だと月別のアーカイブを表示できた。

Hugo で同じようなことをするには、Taxonomy を使うのが一般的なようだ。

しかし、各投稿の Front Matter をいじる必要があるし、生成される URL が /[taxonomy]/[yyyy]/ などになり、自分の希望する構造とは少し異なる。

結局 Blogger と同じ構造のアーカイブを作るのは諦め、1 ページ完結型の年月別アーカイブページを Taxonomy を使わずに作ることにした。

※Hugo v0.151.2 を使用しています。Hugo のバージョンによってはこの記事の方法が使えない場合がありますのでご了承ください。

この記事の目次

アーカイブ用レイアウトを作成する

今回は Taxonomy を使わず、テンプレート内で投稿をまとめてアーカイブを生成する。

ここでは、投稿以外のページ(about や categories など)をアーカイブに含めないように、以下のコードで /content/posts/ 内の投稿に限定している。

{{ $posts := where .Site.RegularPages "Section" "posts" }}

投稿一覧のグループ化には、ページコレクションを日付順にグループ化してくれる GroupByDate を用いた。

アーカイブを導入するには、/layouts/archives.html というレイアウトにこれから紹介するコードを追加すればよい。

用途に応じて 3 パターン用意してみた。

年別のフラット型アーカイブ

年単位で投稿をまとめ、その年に属する記事を一覧表示する。

{{ $posts := where .Site.RegularPages "Section" "posts" }}

<p>全 {{ len $posts }} 件の投稿</p>

{{ range $posts.GroupByDate "2006" }}
<details name="archive-list">
  <summary>{{ .Key }}年({{ len .Pages }})</summary>
  <ul>
  {{ range .Pages }}
    <li>{{ .Date.Format "01/02" }}:<a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
  {{ end }}
  </ul>
</details>
{{ end }}

$posts.GroupByDate "2006" と指定することで、年単位でグループ化される。.Key にはその年(例:2026)が入り、.Pages にその年の投稿一覧が入る。

details, summary でアーカイブを折りたたみ、縦に長くなりすぎないようにした。また、details に共通の name 属性を付け、折りたたみを 1 つだけ開くようにしている。

月別のフラット型アーカイブ

月単位で投稿をまとめ、その月に属する記事を一覧表示する。

{{ $posts := where .Site.RegularPages "Section" "posts" }}

<p>全 {{ len $posts }} 件の投稿</p>

{{ range $posts.GroupByDate "2006年1月" }}
<details name="archive-list">
  <summary>{{ .Key }}({{ len .Pages }})</summary>
  <ul>
  {{ range .Pages }}
    <li>{{ .Date.Format "01/02" }}:<a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
  {{ end }}
  </ul>
</details>
{{ end }}

投稿頻度の多いブログはこちらの形式のほうがおすすめ。ただ、個人的には details を毎回開くのがやや手間に感じたので、この場合なら単なるリスト形式でもいい気がする。

年別→月別の階層型アーカイブ

年単位で投稿をまとめ、その中をさらに月単位で分ける階層型。

{{ $posts := where .Site.RegularPages "Section" "posts" }}

<p>全 {{ len $posts }} 件の投稿</p>

{{ range $year := $posts.GroupByDate "2006" }}
<details name="archive-list">
  <summary>{{ $year.Key }}年({{ len $year.Pages }})</summary>
  <ul>
  {{ range $month := $year.Pages.GroupByDate "1" }}
    <li>{{ $month.Key }}月({{ len $month.Pages }})
      <ul>
      {{ range $month.Pages }}
        <li>{{ .Date.Format "01/02" }}:<a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
      {{ end }}
      </ul>
    </li>
  {{ end }}
  </ul>
</details>
{{ end }}

年別と月別の投稿数の両方を確認したかったため作成した。個人的にはこれがいちばんお気に入りで、2026年2月22日現在では本ブログでもこの形式を採用している。

フラット型に比べ range のネストが深いので、変数名 $year, $month を定義して自分がややこしくならないようにした。

アーカイブ用ページを作成する

/content/archives.md を作成し、先程作成したレイアウトを適用する。TOML 形式の Front Matter の例は以下の通り。

+++
title = "Archives"
slug = "archives"
layout = "archives"
+++

layout = "archives" を指定することで、このページに /layouts/archives.html が適用される。

ここまで終わって /archives/ にアクセスすると、1 ページ完結型のアーカイブが表示される。

Blogger のときと同じ構造とはいかなかったが、Taxonomy を使わずともアーカイブを作ることができた。

こうして投稿一覧を眺めていると、決して更新頻度が高くないこのブログでもなんだかんだ積み上げてきたものはあるのだなあとしみじみしてしまった。作ってよかった。