リストテンプレート (List Templates)

メモ:

トップページや、セクション(カテゴリ)ごとにセクション(カテゴリ)に含まれるコンテンツのタイトルや導入部分を一覧にしたインデックスページを用意する場合があります。 Hugo では、リスト表示のためのリストページテンプレート (List Page Templates)が用意されています。Paper というテーマをもとにリストページテンプレートについて確認していきます。

リストページテンプレート

リストページテンプレートは、1つのHTMLに複数のコンテンツをレンダリングするために使用されるテンプレートです。

Paper というテーマの場合、「themes\hugo-paper\layouts\_default」ディレクトリに用意された list.html がリストページテンプレートにあたります。リストページテンプレートは、「layouts\_default」ディレクトリ以外のも配置することができるのですが、とりあえず全記事ページが同じレイアウトとした場合「layouts\_default」ディレクトリに置くことでテンプレートが適用されます。

それでは、Paper というテーマに用意されたリストページテンプレートを見てみます。

{{ partial "header.html" . }}
{{ if not .IsHome }}
<header class="list-header">
  {{ if eq .Data.Singular "tag" }}<span>Tagged in</span>
  <h1 class="list-title">{{ .Data.Term }}</h1>
  {{ else }}<h1 class="list-title">Posts</h1>
  {{ end }}
</header>
{{ end }}
{{ $paginator := .Paginate (where .Pages ".Params.type" "!=" "page") (index .Site.Params "paginate" | default 10) }}
{{ if gt $paginator.TotalPages 0 }}
  {{ range $index, $page := $paginator.Pages }}
    {{ if and $.IsHome (eq $paginator.PageNumber 1) (eq $index 0) }}
      {{ .Scratch.Set "postClass" "first-entry" }}
      {{ .Scratch.Set "firstEmoji" "<span class=\"welcome-emoji\">👉</span>" }}
    {{ else }}
      {{ .Scratch.Set "postClass" "post-entry" }}
    {{ end }}
    <article class="post {{ .Scratch.Get `postClass` }}">
      <header class="post-header">
        {{ safeHTML (.Scratch.Get `firstEmoji`) }}
        <h2 class="post-title">{{ .Title }}</h2>
      </header>
      <p class="post-summary">{{ .Summary | plainify | htmlUnescape }}...</p>
      <footer class="post-footer">
        <p class="post-meta">{{ .Date.Format "2006.1.2" }}</p>
      </footer>
      <a class="post-link" href="{{ .Permalink }}"></a>
    </article>
  {{ end }}
{{ end }}
{{ if gt $paginator.TotalPages 1 }}
  <footer class="list-footer">
    <nav class="pagination">
      {{ if $paginator.HasPrev }}
        <a class="pagination-prev" href="{{ $paginator.Prev.URL }}">← 上一页</a>
      {{ end }}
      {{ if $paginator.HasNext }}
        <a class="pagination-next" href="{{ $paginator.Next.URL }}">下一页 →</a>
      {{ end }}
    </nav>
  </footer>
{{ end }}
{{ partial "footer.html" . }}

この例では、ページネーションが使われているため少しわかりにくいのですが、リストページテンプレートでは、セクションのリストページでは .Data.Pages にセクションのコンテンツが格納され range から end までの間をループとなるため順にコンテンツの情報を取得することができます。

シンプルな例では、次のように記述します。

<ul>
{{ range .Pages }}
    <li>
        <a href="{{.Permalink}}">{{.Date.Format "2006-01-02"}} | {{.Title}}</a>
    </li>
{{ end }}
</ul>

例えば、次のような記事が用意されている場合、上記例では 「section01」内の article_xx が順に参照され a タグとしてアドレス,日付,タイトルがリストとして出力されます。

content
  |-- section01
  |    +-- article_01.md
  |    +-- article_02.md

<ul>
    <li>
        <a href="http://www.hoge.org/section01/article_01.html">2018-09-07article_01のタイトル</a>
        <a href="http://www.hoge.org/section01/article_02.html">2018-09-10article_02のタイトル</a>
    </li>
</ul>

Paper というテーマでは、10記事ごとにページがまとめられ footer 部分で前後にページを切り替えるつくりとなっています。そのほか、日付順やタイトル順など指定の順序に並べて出力することも可能です。