現在の階層のページ一覧を出力するテンプレートを再帰的に呼び出すようにすると、サイト内の全てのセクションとページを、ツリー構造で表示することができます。 すべてのページのリンクが出力されるので、サイトマップの出力に使用したり、ホームページ用のテンプレートに利用するとよいでしょう。
ツリー出力の基本
下記は、サイト内のすべてのページをツリー形式で表示するサンプルテンプレートです。
セクション変数の .Pages
を参照すると、そのセクションに含まれるサブセクションや通常ページを取得することができるので、それを range
でループ処理しています。
部分テンプレート hierarchy
を定義し、これをホームページ (.Site.Home
) から再帰的に呼び出すことで全ページのツリー構造を出力しています。
<h2>全ページのリスト</h2>
{{- define "hierarchy" }}
<ul>
{{- range .Pages }}
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a>
{{- if .IsSection }}{{ template "hierarchy" . }}{{ end }}
{{- end }}
</ul>
{{- end }}
{{ template "hierarchy" .Site.Home }}
* タイトル A
* セクション 1
* セクション 1-1
* タイトル 1-1-A
* タイトル 1-1-B
* タイトル 1-A
* タイトル 1-B
* タイトル B
* タイトル C
* セクション 2
* セクション 2-1
* タイトル 2-1-A
* タイトル 2-1-B
ここでは、hierarchy
のパラメータとして .Site.Home
を渡しているため、サイト全体のページツリーが出力されていますが、任意のセクションをルートにしてページツリーを出力することができます。
例えば、セクションテンプレートで次のように呼び出せば、現在のページが所属しているセクション (.CurrentSection
) 以下のセクションおよびページをツリー表示できます。
{{ template "hierarchy" .CurrentSection }}
セクションページを優先的に表示する
ページをリスト化するときに、セクションページを通常ページよりも先に表示したいときは、例えば次のようにします。
ここでは、セクションページと通常ページを .Pages
でまとめてループ処理するのではなく、.Sections
でセクションページのみを先にループ処理してから、.RegularPages
で通常ページをループ処理するようにしています。
{{- define "hierarchy" }}
<ul>
{{- /* セクションページをループ処理 */}}
{{- range .Sections }}
<li><a href="{{ .RelPermalink }}">📁{{ .Title }}</a>
{{- template "hierarchy" . }}
{{- end }}
{{- /* 通常の記事ページをループ処理 */}}
{{- range .RegularPages }}
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a>
{{- end }}
</ul>
{{- end }}
{{ template "hierarchy" .Site.Home }}
* 📁セクション 1
* 📁セクション 1-1
* タイトル 1-1-A
* タイトル 1-1-B
* タイトル 1-A
* タイトル 1-B
* 📁セクション 2
* 📁セクション 2-1
* タイトル 2-1-A
* タイトル 2-1-B
* タイトル A
* タイトル B
* タイトル C
ちなみに、セクション名の前にはフォルダアイコンを表示しています(Unicode の数値文字参照で 📁
と書いても OK)。
フォルダアイコンを表示する別の方法として、Hugo の絵文字表示機能 (emojify) を使って、{{ emojify ":open_file_folder:" }}
のように記述する方法もあります。
指定したセクションも含めて表示する
ツリー構造が一段深くなってしまうのでオススメはしませんが、指定したセクション(ルートセクション)も含めてツリー表示するには、例えば次のように実装します。
{{- define "hierarchy" }}
<ul>
<li><a href="{{ .RelPermalink }}">📁{{ .Title }}</a>
{{- range .Sections }}
{{- template "hierarchy" . }}
{{- end }}
{{- range .RegularPages }}
<ul>
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a>
</ul>
{{- end }}
</ul>
{{- end }}
{{ template "hierarchy" .Site.Home }}
次のように、ホームページをルートとしてツリー表示されます。
* 📁ホーム
* 📁セクション 1
* 📁セクション 1-1
* タイトル 1-1-A
* タイトル 1-1-B
* タイトル 1-A
* タイトル 1-B
* 📁セクション 2
* 📁セクション 2-1
* タイトル 2-1-A
* タイトル 2-1-B
* タイトル A
* タイトル B
* タイトル C
2 階層目までを表示する
下記の例では、hierarchy
ローカルテンプレートに level
というパラメータを追加し、そのパラメータで指定した階層までのページリストを表示するように変更したものです。
ここでは level
に 2 を指定して、2 階層目までのページをツリー出力しています。
<h2>2 階層目までのページのリスト</h2>
{{- define "hierarchy" }}
{{- $section := .section }}
{{- $level := .level }}
<ul>
{{- range $section.Pages }}
<li><a href="{{ .RelPermalink }}">{{ if .IsSection }}📁{{ end }}{{ .Title }}
{{- if and .IsSection (gt $level 1) }}
{{- template "hierarchy" (dict "section" . "level" (sub $level 1)) }}
{{- end }}
</li>
{{- end }}
</ul>
{{- end }}
{{ template "hierarchy" (dict "section" .Site.Home "level" 2) }}
* タイトル A
* 📁セクション 1
* セクション 1-1
* タイトル 1-A
* タイトル 1-B
* タイトル B
* タイトル C
* 📁セクション 2
* 📁セクション 2-1
hierarchy
テンプレートを再帰呼び出しするときに、sub
関数で level
パラメータの値を 1 つずつ減らすことで、再帰処理を途中で止めるようにしています。