投稿一覧のページ送りは、メインループなら1行で出せます。
<?php the_posts_pagination(); ?>つまずくのはWP_Queryで作った一覧のほうです。こちらは「今が何ページ目か」をクエリに教える必要があります。順に見ていきます。
メインループのページ送り
home.php・archive.php・category.phpなど、そのページの主役の一覧にはthe_posts_pagination()を使います。見た目の文言も指定できます。
<?php
the_posts_pagination([
'mid_size' => 2, // 現在ページの左右に出す番号の数
'prev_text' => '前へ',
'next_text' => '次へ',
'screen_reader_text' => 'ページ送り', // 見出し(読み上げ用)
]);
?>出力されるHTMLはこんな形です。CSSはこのクラスに当てます。
<nav class="navigation pagination">
<div class="nav-links">
<span aria-current="page" class="page-numbers current">1</span>
<a class="page-numbers" href="…/page/2/">2</a>
<a class="next page-numbers" href="…/page/2/">次へ</a>
</div>
</nav>.pagination .nav-links { display: flex; gap: 0.5rem; justify-content: center; }
.pagination .page-numbers {
padding: 0.4em 0.8em;
border: 1px solid #ddd;
border-radius: 6px;
text-decoration: none;
}
.pagination .page-numbers.current { background: #333; color: #fff; }「前へ/次へ」だけで十分なら、さらに軽い2つの関数もあります。
<?php previous_posts_link('新しい記事へ'); ?>
<?php next_posts_link('古い記事へ'); ?>WP_Queryのサブループのページ送り
自分で作ったクエリは、「今が何ページ目か」を渡さないと永遠に1ページ目を表示します。ここが最大のつまずきポイントです。
<?php
$paged = max(1, (int) get_query_var('paged')); // 今のページ番号(無ければ1)
$query = new WP_Query([
'post_type' => 'shohin',
'posts_per_page' => 12,
'paged' => $paged, // ← これが必須
]);
?>
<?php if ($query->have_posts()) : ?>
<div class="cards">
<?php while ($query->have_posts()) : $query->the_post(); ?>
<article class="card"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></article>
<?php endwhile; ?>
</div>
<?php
// ページ送りの出力(メインクエリではないので自分で組む)
echo '<nav class="pagination">';
echo paginate_links([
'total' => $query->max_num_pages, // 総ページ数
'current' => $paged,
'mid_size' => 2,
'prev_text' => '前へ',
'next_text' => '次へ',
]);
echo '</nav>';
?>
<?php endif; ?>
<?php wp_reset_postdata(); ?>覚えることは3つです。
- クエリに
'paged'を渡す(get_query_var('paged')から取る) paginate_links()にtotalとcurrentを渡す(totalは$query->max_num_pages)- 最後に
wp_reset_postdata()
2ページ目が404になるとき
原因はだいたい次の3つです。上から確認します。
1. 固定ページの中のサブループ(pagedではなくpage)
固定ページ(page.phpやpage-shohin.php)の中でサブループを回すときだけ、ページ番号はpagedではなくpageというクエリ変数に入ります。固定ページのpagedはすでに別の用途で使われているためです。
<?php
$paged = max(1, (int) get_query_var('paged'), (int) get_query_var('page'));
?>max()で両方から拾っておけば、固定ページでもアーカイブでも同じコードが動きます。
2. パーマリンクのルールが古い
投稿タイプやタクソノミーを追加したあとは、URLの変換ルールを作り直す必要があります。管理画面の「設定」→「パーマリンク」を開いて「変更を保存」を押すだけで再生成されます(設定を変えなくてOK)。カスタム投稿タイプ関連の404は、これで直ることがかなり多いです。
3. 1ページ目と件数の食い違い
'posts_per_page' => -1(全件取得)のままpaginate_links()を使うと、総ページ数が1のままになりページ送りが機能しません。ページ送りを付ける一覧では、必ず件数を指定します。
1ページに出す件数を変える
- サイト全体——「設定」→「表示設定」の「1ページに表示する最大投稿数」
- 特定のアーカイブだけ——
pre_get_postsで指定
function my_posts_per_page($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if (is_post_type_archive('shohin')) {
$query->set('posts_per_page', 12);
}
}
add_action('pre_get_posts', 'my_posts_per_page');メインの一覧の件数はこの方法で変えるのが正解です。WP_Queryで作り直すとページ送りやパンくずと食い違いが出ます。
「もっと見る」ボタンにしたいとき
番号ではなくボタンで追加読みこみしたい場合も、土台は同じです。paginate_links()の代わりにnext_posts_link()のURLを使い、JavaScriptで次ページのHTMLを取ってきて差しこみます。まずはページ送りとして正しく動く状態を作ってから、その上に載せるのが安全な進め方です。
まとめ
- メインループのページ送りは
the_posts_pagination()の1行。文言は引数で調整 WP_Queryでは'paged' => get_query_var('paged')とpaginate_links()のtotalが必須- 404のときは固定ページなら
page変数、それ以外はパーマリンク設定の再保存を試す - メインの一覧の件数は
pre_get_postsで変える。クエリを作り直さない
ページ送りが正しく動くと、記事が増えても回遊できるサイトになります。