MENU

WordPress ページネーション講座

目次

1. ページネーションとは

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

ページネーション実装の種類

①超・超シンプルページネーション

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」
  • 総ページ数の指定方法が異なる
    • メインループはグローバル変数にセットされる
      👉️$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とか)」になる
  • メインクエリが固定ページなのか記事一覧ページなのかで、ページネーションの内部的なパラメータが異なる

ページネーションの内部的なパラメータとは(正確には、クエリ変数という)

pagedpage という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
    ));
    
    よかったらシェアしてね!
    • URLをコピーしました!
    • URLをコピーしました!

    この記事を書いた人

    目次