1. ページネーションとは
- コンテンツを複数ページに分割して表示する仕組み
- 「記事一覧のページネーション」と、「1記事内で記事を分割するページネーション」がある

ページネーション実装の種類
①超・超シンプルページネーション
next_posts_link()
と previous_posts_link()
を使った実装
<?php previous_posts_link( '« 新しい投稿' ); ?>
<span>|</span>
<?php next_posts_link( '古い投稿 »' ); ?>
最大ページ数を引数で渡してあげればサブクエリでも使える(らしい。ちょっと今後テストします)
// ページネーションを表示
previous_posts_link('← 新しい投稿', $custom_query->max_num_pages);
next_posts_link('古い投稿 →', $custom_query->max_num_pages);
②もっともシンプルな実装
the_posts_pagination()
を使った実装
the_posts_pagination()
を使った実装
👉️ メインクエリとは???(あとで補足説明を追加する)
- HTMLコードまでまるっと自動生成してくれる(つまり実装が簡単)
- 細かいカスタマイズができない
- WordPress4.1以降から使える
サンプルコード
超シンプルな実装
the_posts_pagination();
オプション付き実装
the_posts_pagination( array(
'mid_size' => 2, // 現在のページの前後に表示するページ数
'prev_text' => 'まえぇ!', // 前のページへのリンクテキスト
'next_text' => 'つぎぃ!, // 次のページへのリンクテキスト
'screen_reader_text' => 'ページナビゲーション' // スクリーンリーダー用テキスト
) );
mid_size => 2
:
- 現在のページ番号の前後に表示するページ番号の数を指定します
- 例えば現在が5ページ目の場合、
mid_size => 2
だと 3, 4, 5, 6, 7 のページ番号が表示されます - デフォルト値も 2 なので、このパラメータは省略可能です
prev_text => '前へ'
:
- 「前のページ」へのリンクに表示するテキストを指定します
- デフォルトは ‘Previous’ (翻訳されたもの) なので、日本語サイトでは変更すると良いでしょう
next_text => '次へ'
:
- 「次のページ」へのリンクに表示するテキストを指定します
- デフォルトは ‘Next’ (翻訳されたもの) なので、日本語サイトでは変更すると良いでしょう
screen_reader_text => 'ページナビゲーション'
:
- スクリーンリーダー用のテキストを指定します
- 視覚的には表示されませんが、スクリーンリーダーを使用している視覚障害者のユーザーにページネーションの目的を説明します
- アクセシビリティ向上のために重要なパラメータです
③こまかなカスタマイズができる実装( pageinate_links() )
paginate_links()
を使った実装- メインクエリでもサブクエリでも使えるページネーション
- こまかなカスタマイズが可能
③-1. メインクエリでの使用例
// メインクエリのページネーション
echo paginate_links(array(
'base' => str_replace(999999999, '%#%', esc_url(get_pagenum_link(999999999))),
'format' => '?paged=%#%',
'current' => max(1, get_query_var('paged')), // メインループではget_query_var()を使用
'total' => $wp_query->max_num_pages, // グローバル変数$wp_queryを参照
'prev_text' => '前へ',
'next_text' => '次へ',
'mid_size' => 2,
'type' => 'list'
));
■ base: ページネーションのベースURLを設定します(URLの型、テンプレみたいなもん)
get_pagenum_link(999999999)
: ページネーションのURL形式を取得(どでかいページで)
👉️ちなみに、99999999に特別な意味はない。たんに「テンプレだよ」ってニュアンスにしたい。esc_url()
: URLをエスケープ(セキュリティ対策)str_replace(999999999, '%#%', ...)
: 999….を %#% に置き換え
👉️%#% はWordPress内にて「これはページネーションのページ数の部分だよ」ってもの。プレースホルダーとか言ったりします。- 結果として、
https://example.com/blog/page/%#%/
みたいなベースURL(テンプレ)が完成
■format: URLでのページ番号の形式を指定
?paged=%#%
: クエリパラメータとして?paged=2
などの形式でページ番号を追加
👉️あまり指定する意味はないかも。base とかパーマリンク設定に依存する。(勉強中)
■current: 現在のページ番号を指定
get_query_var('paged')
: WordPressのクエリから現在のページ番号を取得
👉️URLではなくクエリから取得している。パーマリンク設定でURL変わっても内部的なパラメータpagedやpageの値を取得する(👉️どういうこと?更に詳しく解説を補足するかも)max(1, ...)
: 値が0とかでも「最低でも必ず1」ってやってる
👉️初期表示ではパラメータでページ番号を持っていないので、それでも1にするため
total: 総ページ数を指定
$wp_query->max_num_pages
: メインクエリの総ページ数を参照
prev_text / next_text: 前へ/次へボタンのテキスト
- それぞれ「前へ」「次へ」と日本語で表示
mid_size: 現在のページの前後に表示するページ数
2
: 現在のページの前後に2ページずつ表示する
type: ページネーションの出力形式
'list'
: HTMLのリスト形式(<ul><li>...</li></ul>
)で出力
③-2. サブクエリでの使用例
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'product',
'posts_per_page' => 2,
'paged' => $paged
);
$product_query = new WP_Query($args);
if ($product_query->have_posts())...
〜※省略(ループ処理)〜
// カスタムクエリのページネーション
echo paginate_links(array(
'base' => str_replace(999999999, '%#%', esc_url(get_pagenum_link(999999999))),
'format' => '?paged=%#%',
'current' => max(1, $paged), // 保存した変数を使用
'total' => $product_query->max_num_pages, // カスタムクエリのインスタンスを参照
'prev_text' => '前へ',
'next_text' => '次へ',
'mid_size' => 2,
'type' => 'list'
));
メインクエリとの違いを解説
- 現在のページ番号は自力で取得する必要がある
- 1行目:
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
get_query_var('paged')
:クエリのパラメータ(paged) の値を取得(つまり現在のページ番号)- 値があればその値、なければ(初期表示とか)強制的に「1」
- 1行目:
- 総ページ数の指定方法が異なる
- メインループはグローバル変数にセットされる
👉️$wp_query->max_num_pages
- サブクエリはサブクエリで取得した変数(投稿オブジェクト)から取得する
👉️$custom_query->max_num_pages
- メインループはグローバル変数にセットされる
- 現在のページ番号の取得方法が異なる
- メインループ👉️
get_query_var('paged')
- サブクエリ👉️事前に変数に保存した値
$paged
- ぶっちゃけ、サブクエリも
get_query_var('paged')
でいける。可読性とかの観点から変数にするのが通常モードっぽい。
- メインループ👉️
- サブクエリはpagedパラメータを指定する
- サブクエリ: クエリ作成時に
'paged' => $paged
のように明示的に指定 - メインクエリは自動でやってくれちゃってる。メインクエリ、偉すぎですね。
- ※超ちなみに、pagedの指定によって内部的には「オフセット」が機能している
👉️オフセットとは?(コミュニティ内講座で解説)
- サブクエリ: クエリ作成時に
④1記事内を分割するページナビゲーション
wp_link_pages()
: 単一投稿内の複数ページのナビゲーション
<?php wp_link_pages(); ?>
- 特徴:
<!-- nextpage -->
タグで分割された投稿内での使用
設定→「ホームページの表示」を「固定ページ」にしたときのページネーション
ここでは以下の前提知識が必須
- メインクエリが「固定ページ(たとえばtopとか)」になる
- メインクエリが固定ページなのか記事一覧ページなのかで、ページネーションの内部的なパラメータが異なる
ページネーションの内部的なパラメータとは(正確には、クエリ変数という)
paged と page という2種類のクエリ変数がある
WordPressの「page」と「paged」の基本
「page」と「paged」はWordPressのクエリ変数(Query Variables)です。これらはWordPressのコアに最初から組み込まれている重要な変数で、ページネーションの動作を制御します。
「page」クエリ変数
「page」パラメータは固定ページ内の分割ページに使用されます。
- 用途: 長い固定ページや投稿を複数のページに分割する時に使用
- 分割方法:
<!--nextpage-->
タグをコンテンツ内に挿入
「paged」クエリ変数
「paged」パラメータはアーカイブページの分割に使用されます。
- 用途: 複数の投稿を表示するアーカイブページを分割する時に使用
- 対象ページ: ブログ記事一覧、カテゴリー、タグなどのアーカイブページ
page と paged でのページ番号取得方法の違い
$paged = get_query_var('paged') ? get_query_var('paged') : 1; // アーカイブのページ番号
$page = get_query_var('page') ? get_query_var('page') : 1; // 固定ページ内のページ番号
固定ページをホームページに設定した場合のページネーション
WordPressの「設定」→「表示設定」で「フロントページの表示」を「固定ページ」に設定すると、ページネーションの挙動が少し複雑になります。
固定ページをホームページに設定すると、WordPressはそのページを「固定ページ」として扱います。
ホームページとして設定された固定ページでは、デフォルトでは「page」パラメータ(固定ページ分割用)となる。
よって、記事一覧を表示するための「paged」パラメータは使えない
どうするか?
実装方法(その1):pageクエリ変数をつかう
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
じゃなくて
👇️
$paged = get_query_var('page') ? get_query_var('page') : 1;
にする
実装方法(その2):メインクエリを置き換える(pre_get_posts)
メインクエリが固定ページであるものを、強制的に「記事一覧」に置き換える。
function custom_front_page_query($query) {
// フロントエンドかつメインクエリかつフロントページの場合
if (!is_admin() && $query->is_main_query() && $query->is_front_page()) {
// 投稿タイプを'post'に設定
$query->set('post_type', 'post');
// 表示する投稿数を設定
$query->set('posts_per_page', 5);
// ページネーションを有効にするための設定
// フロントページでは'page'パラメータが使われるため、それを'paged'として使用
$paged = (get_query_var('page')) ? get_query_var('page') : 1;
$query->set('paged', $paged);
return;
}
}
add_action('pre_get_posts', 'custom_front_page_query');
しかしこの方法ってそもそも・・・・
表示設定でホームページを「固定ページ」にしておいて、中のコードでホームページを投稿一覧にしているようなものなので、だったらそもそも表示設定を変えとくのと変わらんのでは・・・
———————– いったんここまで(3/25)
同一ページ内の複数ページネーション
- 異なるクエリパラメータを使用して実装
- それぞれのクエリとページネーションに独自のパラメータ名を指定
- 状態を独立して保持するための設計が重要
4. カスタマイズの方法と考え方
5. 重要な考慮点
アクセシビリティ
- スクリーンリーダー用テキスト
- キーボードナビゲーション対応
- 適切なARIA属性の使用
SEO対策
rel="prev"/"next"
リンク要素の追加- カノニカルURLの設定
- 検索エンジンがコンテンツを適切に理解できる構造
パフォーマンス
- 効率的なクエリ設計
- キャッシュの活用
- 大量データでの最適化テクニック
6. よくある実装パターンと解決策カスタムテンプレートでのページネーション
複数クエリのページネーション
// 独立したページネーションを持つ複数クエリの例
$first_page = isset($_GET['first_page']) ? intval($_GET['first_page']) : 1;
$first_query = new WP_Query(array(
'post_type' => 'post',
'posts_per_page' => 5,
'paged' => $first_page
));
$second_page = isset($_GET['second_page']) ? intval($_GET['second_page']) : 1;
$second_query = new WP_Query(array(
'post_type' => 'product',
'posts_per_page' => 6,
'paged' => $second_page
));
// 第一クエリのページネーション
echo paginate_links(array(
'base' => add_query_arg('first_page', '%#%'),
'format' => '',
'current' => $first_page,
'total' => $first_query->max_num_pages
));
// 第二クエリのページネーション
echo paginate_links(array(
'base' => add_query_arg('second_page', '%#%'),
'format' => '',
'current' => $second_page,
'total' => $second_query->max_num_pages
));