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>';
}
}関数のポイント解説
'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.phpやcategory.php、index.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; ?>カスタム投稿タイプ(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;
?>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;
}まとめ
paginate_links()を配列として扱うことで、WordPressのページネーションは飛躍的に柔軟になります。今回作成した関数をベースに、さらに独自のクラスを追加したり、構造を変更したりすることも簡単です。

