.Pages のデフォルトソート順序
Hugo のセクションページのテンプレート内で .Pages 変数を参照すると、子セクションや子ページの一覧を取得できますが、その一覧はデフォルトで次のような情報をもとにソートされています(参考: Lists of Content in Hugo - Order Content)。
Weight- ページのフロントマターで
weight: 1のように書いておくと、ページに重み付けできます。 より小さな値のweightを持っているページの方が先に表示されます。weightを持たないページ(あるいはweight: 0のページ)は、いかなるweightを持つページよりも後ろに表示されます。
- ページのフロントマターで
Date- ページのフロントマターで、
date: "2022-05-20"のように記述しておくと、そのページの作成日として認識されます。 より新しいページが先に表示されます。
- ページのフロントマターで、
LinkTitle/Title- ページのタイトルで昇順ソートされます。
フロントマターに
linkTitleが指定されていればその値でソートされ、なければtitleの値でソートされます。
- ページのタイトルで昇順ソートされます。
フロントマターに
FilePath.mdファイルのフルパスで昇順ソートされます。
具体的のどのような実装になっているかは、下記 Hugo ソースコードの DefaultPageSort 関数あたりを見ると分かります。
ソート方法をカスタマイズする
.Pages 変数でページの一覧を取得するときに .Pages.ByTitle のように指定すると、ページタイトルでソートされた結果を取得できます。
他にもいろいろな参照方法があります。
| 参照方法 | 意味 |
|---|---|
.Pages.ByWeight | フロントマターの weight の小さい順。ただし、weight: 0 は指定なしとみなされる |
.Pages.ByTitle | タイトル (title) 順 |
.Pages.ByLinkTitle | タイトル (linkTitle) 順。linkTitle がない場合は title を参照する |
.Pages.ByDate | 日付 (date) が新しい順 |
.Pages.ByPublishDate | 日付 (publishdate) が新しい順 |
.Pages.ByExpiryDate | 日付 (expirydate) が新しい順 |
.Pages.ByLastmod | 日付 (lastmod) が新しい順 |
.Pages.ByLength | 本文が短い順 |
.Pages.ByParam "rating" | フロントマターの独自フィールドの値でソート(この場合は rating) |
.Pages.ByParam "author.last_name" | 上の応用(入れ子になった独自フィールド) |
逆順にしたいときは、後ろに .Reverse を付けます。
例えば次のようにすると、タイトルで降順ソート されます。
.Pages.ByTitle.Reverse
セクションテンプレートの中に、次のようなスニペットを記述すれば、各種ソート条件でどのように表示されるかを確認できます。 この例では、ページタイトルで逆順ソートした結果を表示しています。
<ul>
{{ range .Pages.ByTitle.Reverse }}
<li><a href="{{ .RelPermalink }}">{{ .Weight }} / {{ .Date.Format "2006-01-02" }} / {{ .LinkTitle }}</a></li>
{{ end }}
</ul>応用: 複数の条件でソートする
前述の通り、.Pages はデフォルトで Weight → Date → LinkTitle → FilePath の優先度でソートされるのですが、これをカスタマイズして Weight → LinkTitle の順でソートしたい場合はちょっとややこしいです。
.Pages.ByWeight.ByTitle
としてしまうと、Weight 順にソートされた結果がタイトル順で再度ソートされるだけでうまくいきません(.ByWeight の意味がなくなってしまいます)。
段階的にソートするには、まずグループ機能で同じ Weight を持つページを取り出し、そのグループ内でタイトル順ソートする必要があります。
次のパーシャルテンプレートは、渡された .Pages を Weight → LinkTitle の順でソートする関数です。
{{- $pages := . }}
{{- $pagesWithWeight := where $pages "Weight" "<>" 0 }}
{{- $pagesWithoutWeight := where $pages "Weight" "==" 0 }}
{{- $ret := slice }}
{{- range $pagesWithWeight.GroupBy "Weight" }}
{{- $ret = $ret | append .Pages.ByLinkTitle }}
{{- end }}
{{- $ret = $ret | append $pagesWithoutWeight.ByLinkTitle }}
{{- return $ret }}あとは、セクションテンプレートなどから次のように使用します。
<ul>
{{ range partial "functions/sort-pages" .Pages }}
<li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
{{ end }}
</ul>