Hugoで関連記事の代わりに同じカテゴリーの記事を表示する

Hugoで関連記事の代わりに同じカテゴリーの記事を表示する
Page content

Hugoで関連記事を取得する機能を試してみたのですが、記事が少ないせいかほとんどの記事で関連記事が取得できませんでした。

そこで、関連記事の代わりに同じカテゴリーの記事を表示するようにしてみました。

同じカテゴリーの記事表示用の部品を作成

「layouts/partials/related.html」を作成しました。
Mainroadテーマの「RECENT POSTS」(layouts/partials/widgets/recent.html)の記述を持ってきたので、同様の見た目になります。

全体

{{ if and (.Params.categories) }}
{{ $category := index .Params.categories 0 }}
{{ $related := index .Site.Taxonomies.categories (lower $category) | first 4 }}
{{ $current := .RelPermalink }}
{{ with $related }}
{{ if ne (len .) 1 }}
<h4 class="widget__title">Related Posts</h4>
<ul class="widget__list">
  {{ range .}}
  {{ if ne ($current) (.RelPermalink) }}
  <li class="widget__item"><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
  {{ end }}
  {{ end }}
</ul>
{{ end }}
{{ end }}
{{ end }}

やっていること

ほとんどの部分は参考にさせていただいたこちらの記事のままです。
[Hugo] 記事下に同じカテゴリの記事一覧を表示する - michimani.net

  1. 現在の記事と同じカテゴリーの記事の最初の4件を変数に格納

    {{ $category := index .Params.categories 0 }}
    {{ $related := index .Site.Taxonomies.categories (lower $category) | first 4 }}
    
    • .Site.Taxonomies.categories
      下記のようなカテゴリーごとの記事のデータを取得できます。

      map[
        blog:[WeightedPage(0,"aaa") WeightedPage(0,"bbb") WeightedPage(0,"ccc")]
        pc:[WeightedPage(0,"ddd") WeightedPage(0,"eee")]
        procedure:[WeightedPage(0,"fff")]
        programming:[WeightedPage(0,"ggg")]
      ]
      
    • lower $category
      この記事の場合は$categoryに「Blog」が格納されるため、上記データと一致するように小文字変換します。

    • | first 4
      最初の4件を取得しています。
      新着順に4件取れるようです。

  2. 現在のページの相対リンクを変数に格納

    {{ $current := .RelPermalink }}
    

    表示時に現在の記事を除外するために変数に格納しておきます。

  3. 同一カテゴリーの記事が1件(現在の記事のみ)の場合は表示しない

    {{ with $related }}
    {{ if ne (len .) 1 }}
    ...
    {{ end }}
    {{ end }}
    
  4. 現在の記事を除外して表示

    {{ if ne ($current) (.RelPermalink) }}
    <li class="widget__item"><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
    {{ end }}
    

作成した部品を記事画面の下部に表示

Mainroadテーマでは、「layouts/_default/single.html」にrelated.htmlの読み込みを追加すればOKです。

{{ define "main" }}
<main class="main" role="main">
	<article class="post">
...
	</article>
</main>
{{ partial "authorbox.html" . }}
{{ partial "pager.html" . }}
{{ partial "related.html" . }}{{/* こちらを追加 */}}
{{ partial "comments.html" . }}
{{ end }}