初心者必見!WordPressでページネーションを実装する方法を徹底解説(自作コード付き)
みなさんこんにちは!エンジニアの高澤です!
今回はWordPressのページネーションの実装方法について解説していきたいと思います。
ページネーションはWordPressのみならずメディアサイトなどのWebサイトでは必須の機能といっても過言ではありません。
よろしければぜひ当記事をご活用いただき、WordPressにおけるページネーションの実装方法について学習してお仕事や個人ブログの構築などにお役立ていただけましたら幸いです。
目次
ページネーションとは
ページネーションとは、「ページを分割して2ページ目以降に遷移するボタン」のことをいいます。
例えば、ブログやメディアサイトなどでは記事の一覧ページがあり、1ページあたり10件などと区切りのいい数で区切られているページがあるかと思います。
そしてページ下を見ていただくと大体数字が振られたボタンが横に並んでいるような形でボタンが設置されていることがあるかと思いますが、それがいわゆるページネーションなわけです。
WordPressではページネーション実装用のテンプレートタグ(関数)が用意されており、簡単にかつ柔軟に実装することが可能です。
ページネーションのメリット
それではページネーションが必要なのでしょうか?
理由は、「ページ表示スピードが遅くなることを防止すること」と「ユーザーの閲覧性や使いやすさなどを向上すること」にあります。
例えば記事一覧ページとして記事を全件表示させる際に100件以上表示させなければいけない場合、ページを一つで完結して全件表示させるのと、ページをページネーションによって分割して全件表示させるのとはHTMLの出力量が圧倒的に変わり、1ページあたりの容量の重さにかなり違いが出るためページ表示スピードに大きな違いがあります。
また、100件以上ともなるとさすがにページが縦に全体が長くなってしまいサイト全体的な使いやすさが損なわれてしまう可能性があります。
そういったことで、ページネーションのメリットがあるかと思います。
ページネーションを実装する方法
それでは早速WordPressでのページネーションの実装方法について解説していきたいと思います。
ページネーションの実装方法の種類としては以下になるかと思います。
- メインループにて実装する
- サブループにて実装する
それではそれぞれ解説していきます。
「メインループ」と「サブループ」はWordPressループの種類です。
ループについては当記事では解説いたしませんので、別の記事でご確認いただけますと幸いです。
メインループにて実装する場合
メインループにて実装するコードは以下になります。
以下のコードを試しにindex.php、もしくはarchive.phpなどにコピー&ペーストして表示を確認してみてください。
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<!-- 投稿の表示 -->
<?php endwhile; ?>
<!-- ページネーションの表示 -->
<?php
the_posts_pagination( array(
'mid_size' => 2,
'prev_text' => __( '« 前へ' ),
'next_text' => __( '次へ »' ),
) );
?>
<?php else : ?>
<p><?php echo esc_html( '投稿がありません' ); ?></p>
<?php endif; ?>
このあと後述するサブループでの実装よりかはコードが少なめです。
メインループでのページネーションの実装ではthe_posts_pagination()関数を使用します。
ご覧いただくと分かるかと思いますが、while文でループして出力する記述の直下にthe_posts_pagination()関数を記述しているだけです。
the_posts_pagination()関数の引数としてarrayを使ってパラメーターを設定してオプションの変更を加えてることによってページネーションの出力を柔軟にカスタマイズすることが可能です。
みなさんは問題なく表示されましたでしょうか?
メインループとの組み合わせで実装する場合の使用例
次は、このメインループにて実装する場合のPHPテンプレートファイルの種類についてここでしっかり確認しておきたいと思います。
結論以下の内容となります。
- index.php:
これは WordPress テーマの基本的なテンプレートファイルであり、メインループが表示されます。index.php ファイルが存在しない場合、WordPress はデフォルトのテンプレートファイルを探します。 - archive.php:
このテンプレートファイルは、投稿アーカイブページ(カテゴリ、タグ、日付など)の表示に使用されます。メインループがアーカイブページで表示されるため、archive.php ファイル内でページネーションを実装することができます。 - category.php や tag.php:
これらのテンプレートファイルは、特定のカテゴリやタグの投稿が表示される場合に使用されます。メインループがこれらのページで表示されるため、それらのテンプレートファイル内でページネーションを実装できます。 - archive-{post_type}.php:
カスタム投稿タイプのアーカイブページのテンプレートファイルです。メインループがカスタム投稿タイプのアーカイブページで表示されるため、このテンプレートファイル内でページネーションを実装できます。
上記のPHPテンプレートファイルではメインループを利用することが可能です。
そのため、これらのPHPテンプレートファイルの中で、メインループが表示される箇所にthe_posts_pagination()関数を記述することによってページネーションを実装することが可能です。
the_posts_pagination()関数とは
the_posts_pagination()関数は、メインループにおいてWordPressでページネーションを表示するためのテンプレートタグ(WordPress専用の関数)のことを言います。
<!-- ページネーションの表示 -->
<?php
the_posts_pagination( array(
'mid_size' => 2,
'prev_text' => __( '« 前へ' ),
'next_text' => __( '次へ »' ),
) );
?>
WordPressループで出力された記事一覧にページネーションを表示する際に利用されます。
この関数は、以下の内容で引数にパラーメータを設定してページネーションを柔軟にカスタマイズすることができます。
パラメーター名 | 内容 | 初期値 |
base | ページネーションのリンクに使用される基本のURLを指定します。 | %_% |
format | ページネーションのリンクのパーマリンク構造を指定します。 | ?page=%#% |
total | 総ページ数を指定します。 | 1(1ページのみがある場合) |
current | 現在のページ番号を指定します。 | 0(現在のページ番号が自動的に設定されます) |
show_all | 全てのページ番号を表示するかどうかを指定します。 | false(falseの場合、end_sizeおよびmid_sizeで指定した数のページ番号が表示されます) |
end_size | ページ番号リストの両端に表示するページ数を指定します。 | 1 |
mid_size | 現在のページの両端に表示するページ数を指定します。 | 1 |
prev_next | ページネーションに「前へ」「次へ」のリンクを表示するかどうかを指定します。 | true |
prev_text | 「前へ」のリンクのテキストを指定します。 | ‘« Previous’ |
next_text | 「次へ」のリンクのテキストを指定します。 | ‘Next »’ |
type | 戻り値の形式を指定します。’plain’ または ‘list’ を指定します。 | ‘plain’ |
add_args | 追加のクエリ引数を指定する配列を指定します。 | false |
add_fragment | リンクに追加するフラグメント(#fragment)を指定します。 | false |
before_page_number | 各ページ番号の前に挿入するテキストを指定します。 | 空文字列 |
after_page_number | 各ページ番号の後に挿入するテキストを指定します。 | 空文字列 |
screen_reader_text | スクリーンリーダー用のテキストを指定します。 | ‘Posts Navigation’ |
この関数は通常メインループの下に配置され、メインループの投稿がある場合にページネーションを表示します。
この関数を記述するだけで、WordPressが自動的に現在のページを検知しページネーションを生成してくれます。
ページネーションのHTMLが出力されたらCSSで任意にレイアウトをカスタマイズしてください。
メインループの表示件数を設定する方法
メインループにてページネーションを実装した場合、デフォルトでは10件表示で区切られることになります。
これはWordPressインストール直後では決まって10件に設定されておりますので、区切りたい件数を変えたい場合は管理画面から件数を設定します。
変更するには、管理画面左メニューにある「設定」→「表示設定」で進めていき、「1ページに表示する最大投稿数」の「10」を変更したい数字に変更します。
設定が完了したら、「変更を保存」ボタンをクリックして完了です。
設定していただいた数ごとにページが区切られて、ページネーションのボタンの数が調整されたかと思います。
サブループにて実装する場合
メインループの次は、サブループにてページネーションを実装する方法について解説していきたいと思います。
サブループとは、メインクエリとは別のWordPressループのことをいいます。
例えばメインループとは別にサイドバーに記事一覧を表示させるなど一つのページに複数のWordPressループを表示させたい場合や、page.phpの固定ページなど、通常メインループが使えないPHPテンプレートファイルにてWordPressループを使いたい場合にサブループを使います。
サブループにてページネーションを実装するにはまたメインループとは違う実装方法になるので、ここで確認しておきましょう。
サブループにて実装するコードは以下になります。
<?php
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$args = array(
'post_type' => 'post', // 投稿タイプを指定
'posts_per_page' => 10, // 1ページあたりの投稿数を指定
'paged' => $paged // ページ番号を指定
);
$my_query = new WP_Query( $args );
?>
<?php if ( $my_query->have_posts() ) : ?>
<?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>
<!-- 投稿の表示 -->
<?php echo get_the_title(); ?>
<?php endwhile; ?>
<!-- ページネーションの表示 -->
<?php
echo paginate_links( array(
'total' => $my_query->max_num_pages, // 全ページ数を指定
'current' => max( 1, $paged ), // 現在のページ番号を指定
'prev_text' => '« 前へ', // 「前へ」のテキスト
'next_text' => '次へ »', // 「次へ」のテキスト
) );
?>
<?php wp_reset_postdata(); ?>
<?php else : ?>
<p>投稿が見つかりません。</p>
<?php endif; ?>
上記のコードについて詳しく解説いたします。
ページ番号の取得
まず以下のコードの部分はページ番号を取得しております。
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
上記コードの$paged
変数は、現在のページ番号を取得します。
WordPressでは、ページ番号を取得するために get_query_var( 'paged' )
を使用します。
もしページ番号が取得できない場合は、デフォルトで1ページ目を設定します。
クエリの設定
次に以下のコードでクエリの設定をしております。
いわゆるパラメーターの設定です。
$args = array(
'post_type' => 'post', // 投稿タイプを指定
'posts_per_page' => 10, // 1ページあたりの投稿数を指定
'paged' => $paged // ページ番号を指定
);
$args
変数は、WP_Query
クラスのインスタンスを生成するための引数の配列です。
上記コードでは、投稿タイプの指定を「post」にし、1ページあたりの投稿数を10に設定し、ページ番号を $paged
に設定しています。
クエリの実行
次にWP_Queryクラスを利用してクエリの実行をおこないます。
$my_query = new WP_Query( $args );
WP_Query
クラスのインスタンスを生成し、引数として $args
を渡してクエリを実行します。
投稿のループ
<?php if ( $my_query->have_posts() ) : ?>
<?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>
<!-- 投稿の表示 -->
<?php echo get_the_title(); ?>
<?php endwhile; ?>
$my_query->have_posts()
は、クエリが投稿を持っているかどうかをチェックします。もし投稿があれば、while
ループ内で各投稿を取得して表示します。
ページネーションの表示
<?php
echo paginate_links( array(
'total' => $my_query->max_num_pages, // 全ページ数を指定
'current' => max( 1, $paged ), // 現在のページ番号を指定
'prev_text' => '« 前へ', // 「前へ」のテキスト
'next_text' => '次へ »', // 「次へ」のテキスト
) );
?>
paginate_links()
関数を使用してページネーションを表示します。
total
パラメーターには総ページ数を、current
パラメーターには現在のページ番号を指定します。
prev_text
パラメーターとnext_text
パラメーターには、前へと次へのリンクのテキストを指定します。
paginate_links()
関数の全てのパラメーターの簡単な説明と初期値を以下に示します。
パラメーター名 | 内容 | 初期値 |
total | 全ページ数を指定します。 | null |
current | 現在のページ番号を指定します。 | 1 |
mid_size | 現在のページの両端に表示するページ番号の数を指定します。 | 2 |
end_size | ページ番号リストの両端に表示するページ番号の数を指定します。 | 1 |
prev_next | 「前へ」、「次へ」のリンクを表示するかどうかを指定します。 | true |
prev_text | 「前へ」のリンクのテキストを指定します。 | ‘« Previous’ |
next_text | 「次へ」のリンクのテキストを指定します。 | ‘Next »’ |
type | 戻り値の形式を指定します。’plain’ または ‘array’ を指定します。 | ‘array’ |
add_args | 追加のクエリ引数を指定する配列を指定します。 | false |
add_fragment | リンクに追加するフラグメント(#fragment)を指定します。 | ” |
before_page_number | 各ページ番号の前に挿入するテキストを指定します。 | ” |
after_page_number | 各ページ番号の後に挿入するテキストを指定します。 | ” |
show_all | 全てのページ番号を表示するかどうかを指定します。 | false |
base | ページリンクのベースとなるURLを指定します。 | ‘%_%’ |
format | ページリンクのパーマリンク構造を指定します。 | ‘?page=%#%’ |
上記をパラメーターの表をもとにご自由にカスタマイズしてください。
wp_reset_postdata()
関数の使用
<?php wp_reset_postdata(); ?>
メインクエリの状態をリセットするために使用されます。これにより、このクエリでの変更が他のクエリに影響を与えないようにします。
サブループとの組み合わせで実装する場合の使用例
サブループでページネーションを実装するためのPHPテンプレートファイルは、通常、以下のいずれかになります。
- sidebar.phpやfooter.phpなど部分パーツ的なPHPテンプレートファイルに記述
- page.phpやpage-{スラッグ名}.phpなどの固定ページを構成するPHPテンプレートファイルに記述
- WordPressループを複数使用したい場合
上記のいずれかの場面などで使用する際にサブループとの組み合わせとしてページネーションを実装することが可能です。
⚪︎件中⚪︎件表示を実装する方法
最後にページネーションとセットで実装される「全⚪︎件中 ⚪︎件〜⚪︎件」の表示の実装方法を解説いたします。
実装パターンは以下の2種類があります。
- メインループで表示する場合
- サブループで表示する場合
違いは、メインループの場合は「$total_posts = $wp_query->found_posts;」の行では「$wp_query」を記述しますが、サブループの場合は「$total_posts = $my_query->found_posts;」といったようにサブループを作成する際にWP_Queryを実行してそれを代入した変数である「$my_query」が指定されております。
$my_queryの記述は当記事の例で記述しておりまして、実際はご自身で記述した変数名になります。
違いはこの1点のみですが、この点に注意してください。
メインループで表示する場合
メインループで表示する場合の解説をいたします。
以下のコードをページネーションのコード付近にコピー&ペーストしてください。
<div class="pnum">
<?php
// 現在のページ番号
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// ページあたりの投稿数
$posts_per_page = 10;
// 総投稿数
$total_posts = $wp_query->found_posts;
// 現在表示している投稿の範囲
$start_post = ($paged - 1) * $posts_per_page + 1;
$end_post = min($paged * $posts_per_page, $total_posts);
// 表示する情報の出力
echo "全{$total_posts}件中 {$start_post}件〜{$end_post}件";
?>
</div>
サブループで表示する場合
サブループで表示する場合の解説をいたします。
以下のコードをページネーションのコード付近にコピー&ペーストしてください。
<div class="pnum">
<?php
// 現在のページ番号
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// ページあたりの投稿数
$posts_per_page = 10;
// 総投稿数
$total_posts = $my_query->found_posts;
// 現在表示している投稿の範囲
$start_post = ($paged - 1) * $posts_per_page + 1;
$end_post = min($paged * $posts_per_page, $total_posts);
// 表示する情報の出力
echo "全{$total_posts}件中 {$start_post}件〜{$end_post}件";
?>
</div>
上記コードによって下図のイメージで「全⚪︎件中 ⚪︎件〜⚪︎件」の表示が実現できます。
上記のように表示されましたでしょうか?
もしうまくいかない場合は、「$my_query->found_posts;」の「$my_query」の記述だったり何かしらのコードの記述がご自身のテーマのプログラムと合っていない可能性があるため、よく確認してみてください。
2ページ目以降がエラーになってしまう場合の原因と対処法
2ページ目以降がエラーになってしまう場合の原因と対処法についてここで解説しておきたいと思います。
おそらくページネーションを実装していて誰もがぶち当たる壁なのではないでしょうか。
うまくいかなくても一回落ち着いていただき、直前まで実装した内容など心当たりあることを思い返してトレースしてみてください。
筆者の経験上以下の内容が原因としてあげられます。
- 固定ページでサブループのページネーションを実装(固定ページで検索結果ページを独自に実装)しており、その固定ページのURLを「/search/」にしている場合(固定ページのURLとWordPress標準の検索結果ページのURLの競合)
- 固定ページでサブループのページネーションを実装しており、その固定ページのURLを例えば「/blog/」にしていて、かつ、カスタム投稿タイプを投稿タイプ名「blog」で実装していてそのカスタム投稿タイプのアーカイブページをONにしている場合(固定ページのURLとカスタム投稿タイプのアーカイブページのURLの競合)
主に固定ページでサブループを実装していて、その固定ページで設定しているURLが原因で2ページ目移行が表示されずエラーになることが多くありました。
手取り早い解決策としては固定ページのURLを変更することが一番早い解決策かと思います。
ご参考にしていただけましたら幸いです。
まとめ
WordPressでページネーションを実装する方法の解説は以上になります。
ページネーションはブログサイトやメディアサイトなどでは必須の機能といっても過言ではありません。
そんなページネーションについて当記事一つで実務で使える粒度で解説しておりますため、よろしければぜひ繰り返しお役立ていただけましたら幸いです。
お気軽に皆さんのご要望をお聞かせください!
どんなに些細なことでも構いません!よろしければ記事や当サイトへの「こんな記事があったら仕事とかで役に立つな〜」や「こうだったらもっと役に立つのに!」といったようなご要望等をお気軽にお聞かせください!今後のサービス改善にお役立てさせていただきます!
例1)Reactの技術記事を書いてほしい!
例2)WordPressの使い方とかを初心者向けに解説してほしい!...など