プラグインを使わずにWordPressにページネーションを実装する方法

WordPressでブログやお知らせ一覧を作成する際に必須となる「ページネーション(ページ送り機能)」。デフォルトのthe_posts_pagination()でも基本的な実装は可能ですが、「もっと自由にHTMLやCSSクラスをカスタマイズしたい!」と感じたことはありませんか?

この記事では、WordPressのコア関数paginate_links()を活用し、再利用可能でカスタマイズ性に優れたページネーションを自作する方法を解説します。

なぜ自作するのか? デフォルト機能との違い

WordPressには the_posts_pagination() という便利な関数が用意されています。しかし、この関数が出力するHTML構造は決まっており、例えばBootstrapのような特定のCSSフレームワークが要求するクラス(例: page-item, page-link)を付与するには、一手間必要です。

今回紹介する方法では、paginate_links()関数を使い、ページネーションの各パーツ(次へ、前へ、ページ番号など)を配列として取得します。これにより、HTML構造をループ処理で自由に組み立てることが可能になり、デザインの要求に柔軟に応えられます。

functions.phpにページネーション関数を定義する

まずは、テーマのfunctions.phpに、ページネーションを生成するための汎用関数を追加します。この関数を一度定義しておけば、サイト内のどこからでも呼び出すことができます。

/** * カスタマイズ可能なページネーションを出力する関数 * @param WP_Query $query WP_Queryオブジェクト (オプション) */function my_custom_pagination( $query = null ) { // $queryが指定されていない場合は、グローバルな$wp_queryを使用 if ( $query === null ) { global $wp_query; $query = $wp_query; } // ページ数が1以下の場合は何も出力しない if ( $query->max_num_pages <= 1 ) { return; } // paginate_linksの引数を設定 $links = paginate_links( array( 'base' => get_pagenum_link(1) . '%_%', 'format' => get_option('permalink_structure') ? 'page/%#%/' : '&paged=%#%', 'current' => max( 1, get_query_var('paged') ), 'total' => $query->max_num_pages, 'prev_text' => '«', 'next_text' => '»', 'type' => 'array', // ★重要:リンクを配列として取得する 'mid_size' => 2, // 現在のページの両側に表示するページ数 'end_size' => 1, // 先頭と末尾に表示するページ数 ) ); // リンクが生成された場合のみHTMLを出力 if ( ! empty( $links ) ) { echo '<ul class="pagination">'; foreach ( $links as $link ) { // 現在のページ番号には 'current' クラスが含まれる if ( strpos( $link, 'current' ) !== false ) { // <span>タグを<li>で囲み、Bootstrap用のクラスを付与 echo '<li class="page-item active" aria-current="page">' . str_replace( 'page-numbers', 'page-link', $link ) . '</li>'; } elseif ( strpos( $link, 'dots' ) !== false ) { // 「...」(三点リーダー) にはクリックできないようにクラスを付与 echo '<li class="page-item disabled">' . str_replace( 'page-numbers', 'page-link', $link ) . '</li>'; } else { // 通常のページリンク echo '<li class="page-item">' . str_replace( 'page-numbers', 'page-link', $link ) . '</li>'; } } echo '</ul>'; }}
PHP

関数のポイント解説

  • 'type' => 'array': paginate_links()の最も重要な設定です。これにより、戻り値がHTML文字列ではなく、リンクパーツごとの配列になります。このおかげで、foreachループで各要素を個別に処理できます。
  • str_replace(): paginate_links()が自動で付与するpage-numbersというクラスを、Bootstrapで使われるpage-linkに置換しています。
  • if (strpos(...) ...): 配列の各要素(リンク文字列)にcurrent(現在のページ)やdots(…)が含まれているかを判定し、それぞれに応じた<li>タグのクラス(active, disabled)を動的に付与しています。

テンプレートファイルから関数を呼び出す

functions.phpに関数を定義したら、あとは表示したい場所で呼び出すだけです。

通常の投稿一覧(archive.phpなど)での使い方

archive.phpcategory.phpindex.phpなど、メインクエリを使用するテンプレートでは、ループの終了後(endwhile;の後)に以下のように記述します。

<?php if ( have_posts() ) : ?> <?php while ( have_posts() ) : the_post(); ?> <?php // 記事のタイトルなどを表示 ?> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <?php endwhile; ?> <?php // ここにページネーションを呼び出す ?> <nav class="pagination-wrapper"> <?php my_custom_pagination(); ?> </nav><?php else : ?> <p>記事が見つかりませんでした。</p><?php endif; ?>
PHP

カスタム投稿タイプ(WP_Query)での使い方

固定ページなどでサブループ(new WP_Query())を使用している場合は、作成したクエリオブジェクトを関数の引数として渡します。

<?php$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;$args = array( 'post_type' => 'news', // カスタム投稿タイプ名 'posts_per_page' => 5, // 1ページあたりの表示件数 'paged' => $paged,);$news_query = new WP_Query( $args );if ( $news_query->have_posts() ) : while ( $news_query->have_posts() ) : $news_query->the_post(); // 投稿タイトルなどを表示 the_title( '<h2>', '</h2>' ); endwhile; // ★作成したクエリを引数に渡す my_custom_pagination( $news_query ); wp_reset_postdata(); // クエリをリセットendif;?>
PHP

CSSでスタイリングする

上記のPHP関数は、Bootstrap 5と互換性のあるHTMLを出力します。
もしBootstrapを導入していない場合は、以下のCSSを参考に独自のスタイルを適用してください。

/* ページネーション全体のコンテナ */.pagination { display: flex; padding-left: 0; list-style: none; border-radius: 0.25rem;}/* 各ページリンクのスタイル */.page-link { position: relative; display: block; padding: 0.5rem 0.75rem; margin-left: -1px; line-height: 1.25; color: #007bff; background-color: #fff; border: 1px solid #dee2e6; text-decoration: none;}.page-link:hover { color: #0056b3; background-color: #e9ecef; border-color: #dee2e6;}/* アクティブ(現在)のページ */.page-item.active .page-link { z-index: 1; color: #fff; background-color: #007bff; border-color: #007bff;}/* 無効化された(クリックできない)リンク */.page-item.disabled .page-link { color: #6c757d; pointer-events: none; background-color: #fff; border-color: #dee2e6;}/* 角丸の調整 */.page-item:first-child .page-link { margin-left: 0; border-top-left-radius: 0.25rem; border-bottom-left-radius: 0.25rem;}.page-item:last-child .page-link { border-top-right-radius: 0.25rem; border-bottom-right-radius: 0.25rem;}
CSS

まとめ

paginate_links()を配列として扱うことで、WordPressのページネーションは飛躍的に柔軟になります。今回作成した関数をベースに、さらに独自のクラスを追加したり、構造を変更したりすることも簡単です。

read next