Hugo でセクションツリーリストを実装する

heroImage

1. はじめに

Hugo では,タグやカテゴリーなどを設定できる Taxonomy 機能の他に,content フォルダ内の階層構造に対応したツリー構造が生成できる Section 機能がデフォルトで提供されています。Section 機能を用いることで,SEO 対策で有効とされている「パンくずリスト」などを容易に実装することが出来ます。本記事では,セクションツリーリストを実装する手順について記述します。また,本記事で行っている作業は Hugo Ver.0.80.0 と Zorin OS 15 Core (Ubuntu 18.04 LTS) の環境下で実行したものです。Hugo は,インストール済みの前提で記述しており,インストール手順などは割愛していることを,ご了承下さい。

2. ソースコード

セクションツリーリストを表示するソースコードを以下に示します。ソースコードは,(1) 1 〜 15 行目の define を用いてテンプレートを定義している部分と,(2) 16 行目の template を用いてテンプレート呼び出している部分の大きく 2 つで構成されています。

(1) では,3 〜 13 行目がループし,ループ内の 11 行目で template を用いて (1) を再帰的に呼び出すことで階層構造に対応しています。また,(2) では 16 行目の引数として .Site を渡すことで,ルート以外の Section ページでも,全てのセクション名を表示することが出来ます。

1
{{ define "section-tree-list" }}
2
<ul>
3
{{ range .Sections }}
4
<li>
5
<a href="{{.Permalink}}"> {{ .Title }} ({{ len .RegularPagesRecursive }}) </a>
6
</li>
7
{{ if (len .Sections) }} {{ template "section-tree-list" . }} {{ end }} {{ end }}
8
</ul>
9
{{ end }} {{ template "section-tree-list" .Site }}

3. 実行環境構築

まず初めに,Hugo コマンドを用いて Hugo のテンプレートを作成します (1) 。次に,_default フォルダの直下に,section.html を作成します (2) 。最後に,content フォルダ内にフォルダと _index.md を作成します (3) 。Hugo では,content フォルダ内で _index.md が存在するフォルダが Section として認識されるので,必ず _index.md を作成しておきます。

Terminal window
1
# (1)
2
$ hugo new site quickstart
3
$ cd quickstart
4
$ ls
5
archetypes config.toml content data layouts static themes
6
7
# (2)
8
$ mkdir ./layouts/_default
9
$ touch ./layouts/_default/section.html
10
$ tree ./layouts/
11
./layouts/
12
└── _default
13
└── section.html
14
15
1 directory, 1 file
16
17
# (3)
18
$ mkdir ./content/Lv1
19
$ mkdir ./content/Lv1/Lv1-1
20
$ mkdir ./content/Lv2
21
$ touch ./content/Lv1/_index.md
22
$ touch ./content/Lv1/Lv1-1/_index.md
23
$ touch ./content/Lv2/_index.md
24
$ echo -e -n "+++\ntitle=\"Lv1\"\n+++" > ./content/Lv1/_index.md
25
$ echo -e -n "+++\ntitle=\"Lv1-1\"\n+++" > ./content/Lv1/Lv1-1/_index.md
26
$ echo -e -n "+++\ntitle=\"Lv2\"\n+++" > ./content/Lv2/_index.md
27
$ tree ./content/
28
./content/
29
├── Lv1
30
│   ├── Lv1-1
31
│   │   └── _index.md
32
│   └── _index.md
33
└── Lv2
34
└── _index.md
35
36
3 directories, 3 files

上記で作成した section.html を以下のように書き換えます。

1
<!doctype html>
2
<html lang="en">
3
<head>
4
<meta charset="UTF-8" />
5
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
<title>Section Tree List</title>
7
</head>
8
9
<body>
10
{{ define "section-tree-list" }}
11
<ul>
12
{{ range .Sections }}
13
<li>
14
<a href="{{.Permalink}}"> {{ .Title }} ({{ len .RegularPagesRecursive }}) </a>
15
</li>
16
{{ if (len .Sections) }} {{ template "section-tree-list" . }} {{ end }} {{ end }}
17
</ul>
18
{{ end }} {{ template "section-tree-list" .Site }}
19
</body>
20
</html>

4. 動作確認

Hugo Server を起動し,http://localhost:1313/lv1/ に任意の Web ブラウザを用いてアクセスします。引数として .Site を設定した場合 (左) と,. を設定した場合 (右) の実行結果を以下に示します。.Site を引数として設定した場合は,Section ページでも全てのセクション名が表示されています。一方で,. を引数として設定した場合は,現在の Section 下に存在するセクション名のみが表示されています。これは,.Site にはサイトのルートに関する情報が,. には現在の Section に関する情報が格納されているためです。

実行結果

5. おわりに

ここまで,セクションツリーリストを実装する手順について記述してきました。「セクションツリーリスト」はブログサイトにとって,基本的にはウィジェットですが,公式サイトでは「パンくずリスト」のサンプルコードは記載されているが,「セクションツリーリスト」のサンプルコードが記載されていなかったり,Section ページで全てのセクション名を表示させるには引数を工夫する必要があるなど,躓く点が複数ありました。本記事が,Hugo テーマ開発者の参考になれば幸いです。