Jekyll製ブログのカテゴリーページにもページネーションを導入する

開発関連技術

ブログ, Ruby, Jekyll


以前、当ブログのカテゴリーページにページネーションを導入したのですが、記事化していなかったので、当時の記録を掘り起こしながら導入手順を書いてみます。

元々あるページネーション#

現時点で、当ブログで使用しているJekyllのバージョンは3.8.1です。
この Jekyll 3系ではデフォルトでjekyll-paginateプラグインが導入されており、トップページではページネーションが有効になっていました。

ただ、カテゴリーページにもページネーションを有効にしたいなと思い調べると、jekyll-paginateプラグインでは対応していないとのこと。
代わりにjekyll-paginate-v2プラグインを使用するように公式でも案内があったため、こちらへ移行することにしました。

jekyll-paginate-v2導入#

※以下導入手順を書いていきますが、使用テーマによって微妙に違いのある可能性があります。
(自分は現時点で Hydeout4.0.2を使用しています)

プラグインのインストール#

Gemfileに追記。

Gemfile
group :jekyll_plugins do
  gem "jekyll-feed", "~> 0.6"
  gem "jekyll-sitemap"
  gem "jekyll-paginate-v2" ←追記
end

インストール.

bundle install

基本設定#

_config.yml#

  1. 使用プラグインを修正
_config.yml
plugins:
  - jekyll-feed
  - jekyll-paginate
  - jekyll-sitemap

_config.yml
plugins:
  - jekyll-feed
  - jekyll-paginate-v2 # 変更
  - jekyll-sitemap
  1. 旧ページネーション設定を書き換え
_config.yml
paginate: 8
paginate_path: "page:num"

_config.yml
pagination:
  enabled: true
  per_page: 10
  permalink: '/page/:num/'
  title: ':title - :num'
  sort_reverse: true
  • enabled:ページネーションの有効化
  • per_page:ページネーションの1ページ当たりのリンク数
  • permalink:ページネーションでページ送りしたときのURL(:numにはページ数が入る)
  • title:ページネーションでページ送りしたときの表示タイトル(:titleにはそのページのタイトル、:numにはページ数)
  • sort_reverse:リンクの並び順を記事が新しい順にするか

_layouts/index.html#

トップページのレイアウトファイルです。
デフォルトではjekyll-paginateが導入されているため、恐らく以下のようなものが含まれていると思われます。

  • pagination-newer.html:ページを1ページ戻す部分
  • pagination-older.html:ページを1ページ進める部分
  • paginator.posts:ページネーションでの1ページあたりの数の記事情報が入っている

ここについては特に変更しなくてよいです。

_layouts/index.html
---
layout: default
---

<div class="content">
  {% include pagination-newer.html %}

  {{ content }}

  {% for post in paginator.posts %}
  <article class="post-body">
    <h2 class="post-title">
      <a href="{{ site.baseurl }}{{ post.url }}">
        {{ post.title }}
      </a>
    </h2>
    {% include post-meta.html post=post %}

    {% if post.excerpt %}
      {{ post.excerpt }}
    {% else %}
      {{ post.content }}
    {% endif %}

    {% if post.excerpt %}
      {% comment %}Excerpt may be equal to content. Check.{% endcomment %}
      {% capture content_words %}
        {{ post.content | number_of_words }}
      {% endcapture %}
      {% capture excerpt_words %}
        {{ post.excerpt | number_of_words }}
      {% endcapture %}

      {% if content_words != excerpt_words %}
        <a href="{{ site.baseurl }}{{ post.url }}">More &hellip;</a>
      {% endif %}
    {% endif %}
  </article>
  {% endfor %}

  {% include pagination-older.html %}
</div>

index.html#

トップページの html ファイルです。

front matter に以下を追記します。
これがないと、レイアウトファイルのpaginator.postsに何も値が入らないため、トップページ表示の際に何も表示されなくなってしまいました。

index.html
pagination:
  enabled: true

※注意点・URL#

使用テーマの影響の可能性もありますが、この設定をしたことで URL が/であるかを条件とした分岐処理が一部うまく動かなくなりました。

その個所については URL が/index.htmlであるかというように修正して対応しました。


この時点ではページネーションの基本設定をやっただけなので、カテゴリーページにページネーションはまだついていません。

カテゴリーページへの設定#

各カテゴリーページのマークダウンファイル#

front matter にページネーションの設定を追記します。

以下は当ブログのプログラミングカテゴリーの例です。
permalinkpaginationが今回必要な設定です。

例.

---
layout: category
title: プログラミング
permalink:  '/プログラミング/'
sidebar_sort_order: 3
pagination:
  enabled: true
  category: プログラミング
  permalink: '/:num/'
---

この場合、URL は(ドメイン)/プログラミング/index.html(ドメイン)/プログラミング/(ページ数)といったようになります。

_layouts/category.html#

カテゴリーページのレイアウトファイルです。
pagination-newer.htmlpagination-older.htmlの include を追記。
加えて、 {% for post in site.categories[category] %}となっていたところを{% for post in paginator.posts %}に。
ページネーションでの1ページあたりの数の記事情報でforを回すようにします。

以下は一例.

_layouts/category.html
---
layout: page
---

{% unless page.content == '' %}
  {{ content }}
{% endunless %}

{% include pagination-newer.html %}

<ul class="posts-list">
  {% assign category = page.category | default: page.title %}
  {% for post in paginator.posts %}
    <li>
      <h3>
        <a href="{{ site.baseurl }}{{ post.url }}">
          {{ post.title }}
          <small>{{ post.date | date_to_string }}
            {% for tag in post.tags %}
              {{ tag }}
            {% endfor %}
          </small>
        </a>
      </h3>
    </li>
  {% endfor %}
</ul>

{% include pagination-older.html %}

これでカテゴリーページでもページネーションが有効になります。

※注意点・カテゴリーページへのリンク#

自分が使用しているテーマの場合、サイドバーにカテゴリーページへのリンクがあり、元々以下のようなコードになっていました。

_includes/category-links.html
{% comment %}
  Dynamically generate list of links to all category pages
{% endcomment %}
{% assign pages_list = site.pages|sort:"sidebar_sort_order" %}
{% for node in pages_list %}
  {% if node.title != null %}
    {% if node.layout == "category" %}
      <a class="category-link {% if page.url == node.url %} active{% endif %}"
          href="{{ node.url | relative_url }}">{{ node.title }}</a>
    {% endif %}
  {% endif %}
{% endfor %}

するとカテゴリーページのページネーションを有効にしたことで、サイドバーのリンクが以下のようになってしまいました。
ページネーションの各ページまでリンクに出てしまっています。

サイドバーのカテゴリーページへのリンク

なので、_includes/category-links.html ファイルを新たに作成して、以下のような内容で上書きするようにしました。
これでページネーションの各ページが出なくなります。

_includes/category-links.html
{% comment %}
  Dynamically generate list of links to all category pages
{% endcomment %}

{% assign pages_list = site.pages|sort:"sidebar_sort_order" %}
{% for node in pages_list %}
  {% if node.title and node.autogen == nil and node.layout == "category" %}
    <a class="category-link {% if page.url == node.url %} active{% endif %}" href="{{ node.url | relative_url }}">{{ node.title | escape }}</a>
  {% endif %}
{% endfor %}

参考リンクまとめ#