【WordPress】固定ページにページネーションを表示する方法

WordPressでは、通常投稿の一覧にページネーションが表示されますが、固定ページにも同じ機能を追加したい場合、少しカスタマイズが必要です。この記事では、WP_Queryを使用して固定ページを取得し、paginate_links()を使ってページネーションを表示する方法を紹介します。

スポンサーリンク

WP_Queryを使用して固定ページを取得する

まず、固定ページにページネーションを追加するために、WP_Queryを使って固定ページの一覧を取得する必要があります。この例では、1ページに5つの固定ページを表示するように設定しています。

NG:固定ページではpagedが空でページが進まない
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

$args = array(
  'post_type'      => 'page',
  'posts_per_page' => 5, // 1ページあたりの表示数
  'paged'          => $paged
);

$query = new WP_Query($args);
?>
<!-- 固定ページでは 'paged' が常に空になり、$paged が常に1のままになる -->
固定ページでは ‘paged’ ではなく ‘page’ を使う
固定ページ(静的ページ)のコンテキストでは、URLの末尾にページ番号を付けてもget_query_var('paged')は空のままです。WordPressは固定ページの末尾の数値をpageクエリ変数(本来は<!--nextpage-->による本文分割ページ送り用)に格納します。このため$pagedが常に1になり、URLは/固定ページ/2/のように正しく見えても表示内容は常に1ページ目のままになってしまいます。'paged'を優先しつつ'page'にフォールバックする書き方にすることで、通常の投稿一覧と固定ページの両方で正しく動作します。
OK:pagedを優先しpageにフォールバック
<?php
// 'paged' を優先しつつ、固定ページでは 'page' にフォールバックする
$paged = get_query_var('paged') ? get_query_var('paged') : ( get_query_var('page') ? get_query_var('page') : 1 );

$args = array(
  'post_type'      => 'page',
  'posts_per_page' => 5, // 1ページあたりの表示数
  'paged'          => $paged
);

$query = new WP_Query($args);
?>

$pagedには、現在のページ番号が設定され、posts_per_pageで1ページあたりに表示する固定ページ数を指定しています。

ループ処理で固定ページを表示する

次に、取得した固定ページをループで表示します。以下のコードを使用して、固定ページのタイトルをリンクとして表示します。

固定ページの一覧を表示するループ
<?php if ($query->have_posts()) : ?>
  <div class="pages-list">
    <?php while ($query->have_posts()) : $query->the_post(); ?>
      <article class="page-item">
        <h2 class="page-title">
          <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
        </h2>
      </article>
    <?php endwhile; ?>
  </div>
<?php endif; ?>

ページネーションを表示する

ページネーションを追加するには、paginate_links()またはthe_posts_pagination()を使います。ただし、この記事のようにカスタムのWP_Queryを使っている場合は、どちらを使うかによって注意点が異なります。

paginate_links()を使用する場合(推奨)

paginate_links()totalcurrentを明示的に指定できるため、カスタムクエリのページネーションに適しています。

paginate_links()でカスタムクエリをページネーション
<?php
$pagination = paginate_links(
  array(
    'total'        => $query->max_num_pages,
    'current'      => $paged,
    'prev_text'    => __('« 前へ'),
    'next_text'    => __('次へ »'),
    'type'         => 'list',
  )
);
if ($pagination) {
  echo '<nav class="pagination">' . $pagination . '</nav>';
}
?>

the_posts_pagination()を使用する場合

the_posts_pagination() はグローバルの$wp_queryしか見ない
the_posts_pagination()はカスタムのWP_Queryオブジェクトを引数として渡す仕組みがなく、常にグローバルの$wp_query(固定ページ自体のメインクエリ)を参照します。この記事の$queryのようなカスタムクエリに対してそのまま呼び出しても、正しくページネーションされません(固定ページ自体はmax_num_pagesが1のため、リンクが表示されないことがほとんどです)。使う場合は、下記のように$wp_queryを一時的にカスタムクエリへ差し替えてから呼び出し、直後に元に戻す必要があります。
the_posts_pagination()を使う場合は$wp_queryを一時的に差し替える
<?php
// the_posts_pagination() はグローバル $wp_query しか見ないため、
// 一時的にカスタムクエリを差し替えてから呼び出す
global $wp_query;
$temp_query = $wp_query;
$wp_query = $query;

the_posts_pagination(
  array(
    'mid_size'  => 2,
    'prev_text' => __('« 前へ'),
    'next_text' => __('次へ »'),
    'screen_reader_text' => __('ページナビゲーション'),
  )
);

// グローバルクエリを元に戻す
$wp_query = $temp_query;
?>

クエリのリセット

WP_Queryを使用した後は、wp_reset_postdata()を使ってクエリをリセットしておくことが重要です。これにより、WordPressのメインクエリが他の部分に影響を与えないようにします。

クエリのリセット
<?php wp_reset_postdata(); ?>

サンプルコード

ここまでの内容をまとめた、固定ページに埋め込んで使える完全なサンプルコードです。ページネーションには、カスタムクエリでも確実に動作するpaginate_links()を使用しています。

固定ページにページネーション付き一覧を表示する完全なコード
<?php
// 'paged' を優先しつつ、固定ページでは 'page' にフォールバックする
$paged = get_query_var('paged') ? get_query_var('paged') : ( get_query_var('page') ? get_query_var('page') : 1 );

// WP_Queryで固定ページを取得
$args = array(
  'post_type'      => 'page',         // 固定ページを指定
  'posts_per_page' => 5,              // 1ページあたりに表示する固定ページ数
  'paged'          => $paged          // 現在のページ番号
);

$query = new WP_Query($args);

// 固定ページのループを開始
if ($query->have_posts()) : ?>
  <div class="pages-list">
    <?php while ($query->have_posts()) : $query->the_post(); ?>
      <article class="page-item">
        <h2 class="page-title">
          <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
        </h2>
      </article>
    <?php endwhile; ?>
  </div>

  <?php
  // ページネーションの表示(paginate_linksを使用。カスタムクエリでも確実に動作する)
  $pagination = paginate_links(
    array(
      'total'        => $query->max_num_pages,
      'current'      => $paged,
      'prev_text'    => __('« 前へ'),
      'next_text'    => __('次へ »'),
      'type'         => 'list',
    )
  );
  if ($pagination) {
    echo '<nav class="pagination">' . $pagination . '</nav>';
  }

  // クエリのリセット
  wp_reset_postdata();

else :
  // 固定ページがない場合のメッセージ
  echo '<p>表示する固定ページがありません。</p>';
endif;
?>

関連記事

よくある質問(FAQ)

Q固定ページにWP_Queryを使ったループのページネーションを追加するには?
A固定ページではget_query_var('page')で現在のページ番号を取得し、WP_Query'paged'引数に渡します。ページネーションリンクの出力には、カスタムクエリのtotal/currentを明示指定できるpaginate_links()を使うのが確実です。
Q固定ページのURLでページネーションが機能しない場合の対処法は?
A固定ページではpagedクエリ変数は空になり、代わりにpageを使います。get_query_var('page')で取得してください。get_query_var('paged')のまま実装すると、URLは変わってもページ2以降の内容が表示されません。
QページネーションのデザインをCSSでカスタマイズするには?
Apaginate_links()が出力するHTMLにはpage-numbersprevなどのクラスが付きます。子テーマのCSSでこれらのクラスにスタイルを定義します。

まとめ

WordPressの固定ページにページネーションを追加することで、ユーザーが固定ページを簡単にナビゲートできるようになります。固定ページでは現在ページの取得にget_query_var('page')を使うこと、カスタムクエリのページネーションにはpaginate_links()を使うことがポイントです。この2点を押さえれば、サイトのユーザビリティを大きく向上させることができます。