まくまくHugo/Goノート
サイト内の全ページの一覧をセクションの階層構造に従って表示する
2018-01-09
下記のテンプレートコードを使用すると、サイト内の全てのセクションと、ページをツリー構造で表示することができます。すべてのページのリンクが出力されるので、サイトマップの出力に使用したり、ホームページ用のテンプレートに利用するとよいでしょう。

ここでは、ホームページ用のテンプレート(layouts/index.html) に適用してみます。

layouts/index.html(抜粋)

<h2>全ページのリスト</h2>

{{- define "hierarchy" }}
  <ul>
    <li><a href="{{ .RelPermalink }}">{{ .Title }}</a>
      {{- /* カレントセクション直下のセクションは再帰処理 */}}
      {{- range .Sections }}
        {{- template "hierarchy" . }}
      {{- end }}

      {{- /* カレントセクション直下のページリスト(ホームだけ特殊処理) */}}
      <ul>
        {{- range (cond .IsHome (where $.Site.RegularPages "Section" "") .Pages) }}
          <li><a href="{{ .RelPermalink }}">{{ .Title }}</a>
        {{- end }}
      </ul>
    </li>
  </ul>
{{- end }}

{{ template "hierarchy" .Site.Home }}

上記のコードでは、部分テンプレート hierarchy を定義し、これをホームページ (.Site.Home) から再帰的に呼び出すことで全ページのツリー構造を出力しています。 ここでは、.Site.Home をルートに設定して呼び出しているため、サイト全体のページツリーが出力されますが、任意のセクションをルートにしてページツリーを出力することもできます。 例えば、セクションテンプレートで下記のように呼び出せば、そのセクション以下のセクションおよびページをツリー表示できます。

{{ template "hierarchy" . }}

出力結果のイメージ(実際には各項目がリンクになります)

* ホーム
    * セクション 1
        * セクション 1-1
            * タイトル 1-1-A
            * タイトル 1-1-B
        * セクション 1-2
            * タイトル 1-2-A
            * タイトル 1-2-B
        * タイトル 1-A
        * タイトル 1-B
    * セクション 2
        * セクション 2-1
            * タイトル 2-1-A
            * タイトル 2-1-B
        * セクション 2-2
            * タイトル 2-2-A
            * タイトル 2-2-B
        * タイトル 2-A
        * タイトル 2-B
    * タイトル A
    * タイトル B

ホームページを表示しない

上記のようにサイトのツリー構造を表示するときに、ホームページを含めてしまうと、その分だけ階層が深くなってしまいます。 ホームページを除いてツリー構造を表示するには以下のようにすればよいでしょう。

layouts/index.html(抜粋)

<h2>全ページのリスト</h2>

{{- define "hierarchy" }}
  <ul>
    {{- /* カレントセクション直下のセクションは再帰処理 */}}
    {{- range .Sections }}
      <li><a href="{{ .RelPermalink }}">{{ .Title }}</a>
        {{- template "hierarchy" . }}
      </li>
    {{- end }}

    {{- /* カレントセクション直下のページリスト(ホームだけ特殊処理) */}}
    {{- range (cond .IsHome (where $.Site.RegularPages "Section" "") .Pages) }}
      <li><a href="{{ .RelPermalink }}">{{ .Title }}</a>
    {{- end }}
  </ul>
{{- end }}

{{ template "hierarchy" .Site.Home }}

出力結果のイメージ

* セクション 1
    * セクション 1-1
        * タイトル 1-1-A
        * タイトル 1-1-B
    * セクション 1-2
        * タイトル 1-2-A
        * タイトル 1-2-B
    * タイトル 1-A
    * タイトル 1-B
* セクション 2
    * セクション 2-1
        * タイトル 2-1-A
        * タイトル 2-1-B
    * セクション 2-2
        * タイトル 2-2-A
        * タイトル 2-2-B
    * タイトル 2-A
    * タイトル 2-B
* タイトル A
* タイトル B

2階層目までを表示する

下記の例では、hierarchy ローカルテンプレートに level というパラメータを追加し、そのパラメータで指定した階層までのページリストを表示するように変更したものです。 ここでは level に 2 を指定して、2 階層目までのページをツリー出力しています。

layouts/index.html(抜粋)

<h2>2 階層目までのページのリスト</h2>

{{- define "hierarchy" }}
  {{- $section := .section }}
  {{- $level := .level }}
  <ul>
    {{- /* カレントセクション直下のセクション */}}
    {{- range $section.Sections }}
      <li><a href="{{ .RelPermalink }}">{{ .Title }}</a> /</li>
      {{- if (gt $level 1) }}
        {{- template "hierarchy" (dict "section" . "level" (sub $level 1)) }}
      {{- end }}
    {{- end -}}

    {{- /* カレントセクション直下のページ(ホームだけ特殊処理) */}}
    {{- range (cond $section.IsHome (where $section.Site.RegularPages "Section" "") $section.Pages) }}
      <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
    {{- end }}
  </ul>
{{- end }}

{{ template "hierarchy" (dict "section" .Site.Home "level" 2) }}

出力結果のイメージ

* セクション 1
    * セクション 1-1
    * セクション 1-2
    * タイトル 1-A
    * タイトル 1-B
* セクション 2
    * セクション 2-1
    * セクション 2-2
    * タイトル 2-A
    * タイトル 2-B
* タイトル A
* タイトル B
2018-01-09