Jekyllのテーマを自作する 基本編 – 第7回 – ページネーションを作成する

Jekyll

今回は、投稿記事ページの前後ページへのリンク作成と、前回作成した記事一覧へのページネーションの機能追加となります。よろしくどうぞ。

投稿記事ページの前後ページへのリンクを作成する

第3回で作成した「_layouts/post.html」はこんな感じです。

---
layout: default
---

<article class="contents page">
  <div class="container">

    <div class="page__header">
      <h1 class="page__title">{{ page.title }}</h1>
      <p class="page__date">{{ page.date | date: '%B %d, %Y' }}</p>
    </div>

    <div class="page__body">


      {{ content }}


    </div><!--page__body-->

    <!-- 前後のページへのリンクを表示したい -->
    <div class="pager">

      <p class="pager__item--next">
        <a href="">&lt; 次のページ</a>
      </p>

      <p class="pager__item--prev">
        <a href="">前のページ &gt;</a>
      </p>

    </div><!--pager-->
    
  </div><!--container-->
</article><!--page-->

これを以下のように修正します。

---
layout: default
---

<div class="contents page">
  <div class="container">

    <div class="page__header">
      <h1 class="page__title">{{ page.title }}</h1>
      <p class="page__date">{{ page.date | date: '%B %d, %Y' }}</p>
    </div>

    <div class="page__body">


      {{ content }}


    </div><!--page__body-->

    <!-- 前後のページへのリンクを表示したい -->
    <div class="pager">

      {% if page.next %}
        <p class="pager__item--next">
          <a href="{{ page.next.url | relative_url }}">&lt; {{ page.next.title }}</a>
        </p>
      {% endif %}

      {% if page.previous %}
        <p class="pager__item--prev">
          <a href="{{ page.previous.url | relative_url }}">{{ page.previous.title }} &gt;</a>
        </p>
      {% endif %}

    </div><!--pager-->
    
  </div><!--container-->
</div><!--page-->
page.next次のページの情報が含まれています。
page.next.url次のページのURLを取得します。
page.next.title次のページのタイトルを取得します。
page.previous前のページの情報が含まれています。
page.previous.url前のページのURLを取得します。
page.previous.title前のページのタイトルを取得します。

プレビューして確認します。前後のページへのリンクが正しく表示されていればOKです。

記事一覧のページネーションを有効にする

ここからは記事一覧のページネーションの作成になります。第1回で全て設定済みではありますが、復習です。Jekyllでページネーションを有効にするには、まず設定ファイル「_config.yml」でgemを読み込みます。

gems:
  - jekyll-paginate

また、同じく設定ファイルに1ページに表示する記事数を設定します。これを書かないとページネーションは有効になりません。

paginate: 3

これで準備完了です。

2ページ目以降のURLを設定する

設定ファイル内で2ページ目以降のURLを設定できます。第一回で、以下のようにデフォルトの設定をそのまま記述しています。

paginate_path: "page:num"

この設定の場合、2ページ目のURLは「http://127.0.0.1:4000/page2/」となります。

記事一覧の「次のページ」「前のページ」リンクを作成する

前回では、 site.posts で全ての記事を取得しましたが、ページネーションを使う場合は、以下のように paginator.posts を使います。これによって、各ページごとに記事をよしなに取得できます。他は同じです。

さらに、「次のページ」「前のページ」リンクをその下に作成します。index.htmlはこのようになります。

---
layout: default
---

<div class="contents front-page">
  <div class="container">

    <!-- 記事一覧 -->
    {% for post in paginator.posts %}
      <article class="archive">
        <h2 class="archive__title"><a href="{{ post.url | relative_url }}">{{ post.title }}</a></h2>
        <p class="archive__date"><time>{{ post.date | date: '%B %d, %Y' }}</time></p>
        <div class="archive__excerpt">{{ post.excerpt }}</div>
      </article>
    {% endfor %}

    <!-- ページネーション -->
    {% if paginator.total_pages > 1 %}
      <div class="pagination">

        {% if paginator.previous_page %}
          <a class="pagination__item" href="{{ paginator.previous_page_path | relative_url }}">&lt; 前のページ</a>
        {% endif %}

        <span class="pagination__item pagination__number">
          {{ paginator.page }} / {{ paginator.total_pages }}
        </span>

        {% if paginator.next_page %}
          <a class="pagination__item" href="{{ paginator.next_page_path | relative_url }}">次のページ &gt;</a>
        {% endif %}

      </div><!--pagination-->
    {% endif %}

  </div><!--container-->
</div><!--main-->
paginator.previous_page前のページのページ番号を取得します。
paginator.previous_page_path前のページのURLを取得します。
paginator.page現在のページのページ番号を取得します。
paginator.total_pagesページの総数を取得します。
paginator.next_page次のページのページ番号を取得します。
paginator.next_page_path次のページのURLを取得します。

あとはスタイルを追記しましょう。

.pagination{
  @include pad();
  display: flex;

  &__item{

    margin-right: 2em;
    text-decoration: none;
    display: block;
  }
}

プレビューしてみます。

2ページ目以降もちゃんと作成されています。

1, 2, 3, … と各ページへリンクするページネーションを作成する

上記では、前後ページへのリンクのみでしたがお次は、1, 2, 3, …と各ページへリンクするページネーションを作成します。

index.htmlを以下のように書き換えます。

---
layout: default
---

<div class="contents front-page">
  <div class="container">

    <!-- 記事一覧 -->
    {% for post in paginator.posts %}
      <article class="archive">
        <h2 class="archive__title"><a href="{{ post.url | relative_url }}">{{ post.title }}</a></h2>
        <p class="archive__date"><time>{{ post.date | date: '%B %d, %Y' }}</time></p>
        <div class="archive__excerpt">{{ post.excerpt }}</div>
      </article>
    {% endfor %}

    <!-- ページネーション -->
    {% if paginator.total_pages > 1 %}
      <div class="pagination">

        {% if paginator.previous_page %}
          <a class="pagination__item" href="{{ paginator.previous_page_path | relative_url }}">&lt; 前のページ</a>
        {% endif %}

        {% for page in (1..paginator.total_pages) %}
          {% if page == paginator.page %}
            <span class="pagination__item current">{{ page }}</span>
          {% elsif page == 1 %}
            <a class="pagination__item" href="{{ site.paginate_path | relative_url | replace: 'page:num', '' }}">{{ page }}</a>
          {% else %}
            <a class="pagination__item" href="{{ site.paginate_path | relative_url | replace: ':num', page }}">{{ page }}</a>
          {% endif %}
        {% endfor %}

        {% if paginator.next_page %}
          <a class="pagination__item" href="{{ paginator.next_page_path | relative_url }}">次のページ &gt;</a>
        {% endif %}

      </div><!--pagination-->
    {% endif %}

  </div><!--container-->
</div><!--main-->

25行目から33行目は、for文で1から最大ページ数までループを回します。

if文を使って、現在のページの場合、1ページへのリンクの場合、その他のページへのリンクの場合と条件分岐します。ちょっと面倒なんですが、1ページ目とその他のページへのリンクURLは条件分岐させて別途作成しなければなりません(Jekyll バージョン3.4現在)。

1ページ目、その他のページのリンクは少し回りくどいやり方をしています。 {{ site.paginate_path }} で、設定ファイルにて設定したパスを読み込んで、1ページ目へのリンクは「page:num」を「”」つまりナシに、その他のページは「:num」の部分をページ番号に置換しています。

なぜ1ページめのリンクが {{ ‘/’ | relative_url }} じゃいけないのかと言いますと、これでは、例えば site.paginate_path: blog/page:num と指定されていた場合に対応できません。

かと言って、 {{ ‘/blog’ | relative_url }} と書くのはいただけない。

site.paginate_path: blog/page:numと指定しているんだから、これを利用するのが筋というもんです。そして、こうしておくことで、paginate_pathの変更にも強いコードとなります。

最後に、ページネーション部分のスタイルを修正します。

.pagination{
  @include pad();
  display: flex;
  flex-wrap: wrap;

  &__item{

    margin-right: 4px;
    text-decoration: none;
    display: block;
    padding: 7px 16px;
    border: $border;
  }

  .current{
    background: $color-main;
    border-color: $color-main;
    color: white;
  }

プレビューして、ページネーションがちゃんと動くか確認します。

3ページ目はこんな感じです。

さて、ページネーションの作成は以上です。次回はフィードの出力についてです。

次は Jekyllのテーマを自作する 基本編 – 第8回 – 記事のフィード(feed.xml)を作成する