list.htmlの作成 アーカイブとページネーション、パンくずリストの解説

こんにちはnasustです。list.htmlの解説をします。 list.htmlは、トップページやアーカイブページで使用します。

list.html

{{ define "content" }}
    {{ $pages := 0 }}
    {{ if .IsHome }}
        {{ $pages = .Site.RegularPages }}
    {{ else if eq .Kind "section" }}
        {{ $section_category_data := partial "function/get_all_category_pages" . }}
        {{ $pages = $section_category_data.all_child_pages }}
    {{ else }}
        {{ $pages = .Pages }}
    {{ end }}

    {{ if eq .IsHome false }}
        <div class="m-list__breadcrumbs">
            {{ partial "breadcrumbs" . }}
        </div>
    {{ end }}

    {{ if $pages }}
        {{ $paginator := .Paginate $pages.ByDate.Reverse 5 }}
        {{ range $paginator.Pages }}
            {{ $page := . }}
            <article class="m-entry">
                <div class="m-entry__header">
                    <div class="m-entry__header-taxonomies">
                            {{ $section_page := .Site.GetPage .Section }}
                            {{ if eq $section_page.IsHome false }}
                                {{ if .CurrentSection }}
                                    <div class="m-entry__header-taxonomies-category">
                                        <span class="m-entry__header-taxonomies-category-title">
                                            <a class="m-entry__header-taxonomies-category-title-link" href="{{ $section_page.Permalink }}">
                                                {{ .CurrentSection.Title }}
                                            </a>
                                        </span>
                                    </div>
                                {{ end }}
                            {{ end }}
                            {{ with .Params.tags }}
                                <div class="m-entry__header-taxonomies-tags">
                                    <ul class="m-entry__header-taxonomies-tags-list" >
                                        {{ range . }}
                                            {{ $name := . }}
                                            {{ with $.Site.GetPage (printf "/%s/%s" "tags" ($name | urlize)) }}
                                                <li class="m-entry__header-taxonomies-tags-list-item">
                                                    <a class="m-entry__header-taxonomies-tags-list-item-link" href="{{ .Permalink }}">{{ $name }}</a>
                                                </li>
                                            {{ end }}
                                        {{ end }}
                                    </ul>
                                </div>
                            {{ end }}
                    </div>
                    <div class="m-entry__header-title">
                        <a class="m-entry__header-title-link" href="{{ .Permalink }}" >
                            <h1 class="m-entry__header-title-link-text">{{ .Title }}</h1>
                        </a>
                    </div>
                    <div class="m-entry__header-date">
                        <time>{{ .PublishDate.Format "2006/01/02" }}</time>
                    </div>
                    {{ $eyecache_data := partial "function/get_eyecache_image" . }}
                    {{ if $eyecache_data.eyecache }}
                        <div class="m-entry__header-eyecache">
                            <img class="m-entry__header-eyecache-img" src="{{ $eyecache_data.eyecache.Permalink }}" >
                        </div>
                    {{ end }}
                </div>
                <div class="m-entry__content">
                    {{ .Summary }}...
                    <a class="a-button" href="{{ .Permalink }}">more</a>
                </div>
            </article>
        {{ end }}
        
        <!-- ページネーション処理 -->

        {{ if eq .IsHome false }}
            <div class="m-list__breadcrumbs">
                {{ partial "breadcrumbs" . }}
            </div>
        {{ end }}
    {{ end }}

{{ end }}
html

長いので分割しています。<!-- ページネーション処理 -->の中身は別の項目で載せています。

記事の一覧は階層型カテゴリーに対応しています。 親のカテゴリーは子のページを全て含みます。

各記事の項目は、アイキャッチ画像、タイトル、サマリー、続きを読むの構成です。 ブログでよくある構成にしています。

パンくずリストも表示します。

define “content”

baseof.htmlの{{block "content"}} {{end}}の内容を上書きします。 list.htmlのテンプレートは、baseof.htmlと{{define "content"}} {{end}}間の内容を合成した結果になります。

see also: Base Templates and Blocks | Hugo

.Kind

ページのタイプを返します。if eq .Kind "section"は、このページがセクションのリストページであるか判定しています。

see also: Page Variables | Hugo

.Site.RegularPages

サイト全体のページ一覧を返します。

see also: Site Variables | Hugo

$pages.ByDate.Reverse

ページの一覧を降順でソートしています。

see also: Lists of Content in Hugo | Hugo

.PublishDate.Format “2006/01/02”

ページの発行日を出力します。.Format "2006/01/02"は時間のフォーマットを指定しています。

see also: dateFormat | Hugo

.CurrentSection

現在のセクションを返します。 .Sectionは一番上の親を返しましたが、こちらは/post/subに所属していればsubセクションを返します。

see also: Page Variables | Hugo

.Paginate

Hugoでページネーションを実現する関数です。

$paginator := .Paginate $pages.ByDate 5で、 ページの配列を時間順でソートを行い、1ページ5件のページネーションを行っています。

see also: Pagination | Hugo

ページネーション処理

<!-- ページネーション処理 -->の中身です。

    {{ if gt $paginator.TotalPages 1 }}
        <div class="m-paginator">
            <ul class="m-paginator__list">
        
                {{ if ne $paginator.PageNumber 1 }}
                    <li class="m-paginator__list-item" ><a class="m-paginator__list-item-link" href="{{ $paginator.First.URL }}">first</a></li>
                {{ end }}
            
                {{ if $paginator.HasPrev }}
                    <li class="m-paginator__list-item"><a class="m-paginator__list-item-link" href="{{ $paginator.Prev.URL }}">prev</a></li>
                {{ end }}
                
                {{ $beginPageNumber := sub $paginator.PageNumber 2 }}
                {{ $endPageNumber := add $paginator.PageNumber 2 }}
                {{ if lt $beginPageNumber 1 }}
                    {{ $addPageNumber := add ( mul $beginPageNumber -1 ) 1 }}
                    {{ $beginPageNumber = add $beginPageNumber $addPageNumber }}
                    {{ $endPageNumber = add $endPageNumber $addPageNumber }}
                {{ else if gt $endPageNumber $paginator.TotalPages }}
                    {{ $subPageNumber := sub $endPageNumber $paginator.TotalPages }}
                    {{ $beginPageNumber = sub $beginPageNumber $subPageNumber }}
                    {{ $endPageNumber = sub $endPageNumber $subPageNumber }}
                {{ end }}

                {{ $pageNumberBeginWhere := where $paginator.Pagers "PageNumber" "ge" (int $beginPageNumber) }}
                {{ $pageNumberEndWhere := where $paginator.Pagers "PageNumber" "le" (int $endPageNumber ) }}
                
                {{ $pageNumberWhere := $pageNumberBeginWhere | intersect $pageNumberEndWhere }}

                {{ range $pageNumberWhere }}
                    <li class="m-paginator__list-item" >
                        {{ $link_class := "m-paginator__list-item-link"  }}
                        {{ if eq . $paginator }} {{ $link_class = "m-paginator__list-item-link--current"}} {{ end }}
                        <a class="{{ $link_class }}" href="{{ .URL }}">{{ .PageNumber }}</a>
                    </li>
                {{ end }}
            
                {{ if $paginator.HasNext }}
                    <li class="m-paginator__list-item" ><a class="m-paginator__list-item-link" href="{{ $paginator.Next.URL }}" class="next">next</a></li>
                {{ end }}
            
                {{ if ne $paginator.PageNumber $paginator.TotalPages }}
                    <li class="m-paginator__list-item" ><a class="m-paginator__list-item-link" href="{{ $paginator.Last.URL }}">last</a></li>
                {{ end }}
            </ul>
        </div>
    {{ end }}
html

$paginator.TotalPages

総ページ数を返します。

see also: Pagination | Hugo

$paginator.First.URL

最初のページのURLを返します。

see also: Pagination | Hugo

$paginator.HasPrev

現在のページから前のページが在る場合はtrueを返します。

see also: Pagination | Hugo

$paginator.Prev.URL

現在のページから前のページのURLを返します。

see also: Pagination | Hugo

$paginator.Pagers

ページネーションで分割されたページ一覧を返します。

このページ一覧は普通にrangeで回すと100ページあったら、 100ページ分のリンクを作成してしまうので、 5ページ分のみ表示するようにしています。

例: first prev 7 8 10 11 12 next last

see also: Pagination | Hugo

where

whereはSQLライクに一覧から条件に一致するものを摘出します。

{{ $pageNumberBeginWhere := where $paginator.Pagers "PageNumber" "ge" (int $beginPageNumber) }}
{{ $pageNumberEndWhere := where $paginator.Pagers "PageNumber" "le" (int $endPageNumber ) }}

{{ $pageNumberWhere := $pageNumberBeginWhere | intersect $pageNumberEndWhere }}

{{ range $pageNumberWhere }}
html

$beginPageNumberが7、$endPageNumberが12で、ページ7,8,9,10,11,12が摘出されます。 whereを利用して5件分のページを取得しています。

SQLライクに表現するとwhere PageNumber >= $beginPageNumber and PageNumber <= $endPageNumberです。

これを利用することでhugoの配列は色々な条件で絞り込みできます。

$beginPageNumberなどは数値の変数ですが、intで明示的に変換しないと正常に動作しないようです。 将来のバージョンでは必要なくなるかもしれません。

see also: where | Hugo

intersect

複数のwhereをANDで一緒にできます。

{{ $pageNumberWhere := $pageNumberBeginWhere | intersect $pageNumberEndWhere }}で2つのwhereをANDで合成しています。

see also: intersect | Hugo

$paginator.HasNext

現在のページから次のページがある場合はtrueを返します。

see also: Pagination | Hugo

$paginator.Next.URL

次のページのURLを返します。

see also: Pagination | Hugo

$paginator.Last.URL

最後のページのURLを返します。

see also: Pagination | Hugo

<div class="a-breadcrumbs">
    {{ $current_page := . }}
    {{ $parents := partial "function/get_parents_list.html" . }}
    {{ $position := 0 }}

    <ul class="a-breadcrumbs__list" itemscope itemtype="http://schema.org/BreadcrumbList" >
        {{ range $parents }}
            <li class="a-breadcrumbs__list-item" itemscope itemprop="itemListElement" itemtype="http://schema.org/ListItem">
                <a class="a-breadcrumbs__list-item-link" href="{{ .Permalink }}" itemprop="item" >
                    {{ if .IsHome }}
                        <span itemprop="name">Home</span></span>
                    {{ else }}
                        <span itemprop="name">{{ .Title }}</span>
                    {{ end }}
                    {{ $position = add $position 1 }}
                    <meta itemprop="position" content="{{$position}}" />
                </a>
                {{ if ne . $current_page }}<span class="a-breadcrumbs__list-item-link-gt">{{ ">" }}</span>{{ end }}
            </li>
        {{ end }}
    </ul>
</div>
html

パンくずリストのテンプレートです。 Googleのデータ構造に対応しています。

get_parents_list.htmlを呼び出すと現在のページからホームまでの親子の一覧を返します。

see also: パンくずリスト | 検索 | Google Developers

get_parents_list.html部分テンプレート

{{ return partial "function/get_parent" (dict "page" . )}}
html

get_parent.htmlを呼ぶ最初の起点です。

get_parent.html部分テンプレート

{{ $parent := false }}

{{ if .page.Parent }}
    {{ $parent = partial "function/get_parent" (dict "page" .page.Parent ) }}
{{ else if not .page.IsHome }}
    {{ $parent = partial "function/get_parent" (dict "page" .page.Site.Home ) }}
{{ end }}

{{ $list := slice .page }}
{{ if $parent }}
    {{ $list = $parent | append $list }}
{{ end }}

{{ return $list }}
html

親のページがあれば、再帰的に自分自身のテンプレートを呼びます。

.Parent

親のページを返します。

see also: Page Variables | Hugo

次回はsingle.htmlを解説します。

prevnext