【WordPress】一覧に「全◯件中◯件〜◯件目を表示」を実装する方法|found_posts・0件対応・WP_Query対応

一覧ページに「全120件中 11件〜20件目を表示」のような表示範囲の情報を出すと、訪問者は「どこまで見たか・あと何件あるか」を把握でき、利便性が上がります。この記事では、その計算と出力を0件時のガードやカスタムWP_Query対応まで含めて解説します。

この記事でわかること

  • 総件数(found_posts)・開始/終了番号の計算方法
  • 0件のときに表示が壊れないようにするガード
  • メインクエリでの完全版(コピペ用)
  • カスタムWP_Queryで使う場合の書き方
スポンサーリンク

計算に使う3つの値

必要なのは①現在のページ番号 ②1ページの表示件数 ③総件数の3つです。メインクエリでは次のように取得します。

PHP:3つの値を取得
global $wp_query;

$paged          = max(1, get_query_var('paged')); // 1ページ目は0が返るため1に
$posts_per_page = (int) get_query_var('posts_per_page');
$total_posts    = (int) $wp_query->found_posts;   // クエリにマッチする総件数

開始番号と終了番号は次の式で計算します。最終ページでは min() で総件数に丸めるのがポイントです(例:全23件・10件表示の3ページ目は「21件〜23件目」)。

PHP:開始番号と終了番号を計算
$start_num = ($paged - 1) * $posts_per_page + 1;
$end_num   = min($paged * $posts_per_page, $total_posts); // 最終ページの端数を丸める

0件のときの表示を必ずガードする

ガードが無いと「全0件中1件〜0件目」と表示される
検索結果が0件のときなど、$total_posts が 0 だと開始番号1・終了番号0という壊れた表示になります。if ($total_posts > 0) のガードを必ず入れ、0件時は非表示にするか「該当する記事がありません」を出しましょう。

完全なコード例(メインクエリ・コピペ用)

archive.phpsearch.php などのループの前後に設置します。

PHP:完全版(0件ガード付き)
<?php
global $wp_query;

$paged          = max(1, get_query_var('paged'));
$posts_per_page = (int) get_query_var('posts_per_page');
$total_posts    = (int) $wp_query->found_posts;

if ($total_posts > 0) {
  $start_num = ($paged - 1) * $posts_per_page + 1;
  $end_num   = min($paged * $posts_per_page, $total_posts);

  echo '<p class="posts-count">'
    . '全' . $total_posts . '件中 '
    . $start_num . '件〜' . $end_num . '件目を表示'
    . '</p>';
} else {
  echo '<p class="posts-count">該当する記事がありません。</p>';
}
?>
posts_per_page が -1 のクエリでは使えない
posts_per_page => -1(全件表示)のクエリでは1ページの件数が確定しないため、この計算は成り立ちません(そもそも全件表示なら範囲表示は不要です)。ページ送り本体の実装はプラグインなしでページネーションを実装する方法を参照してください。

カスタムWP_Queryで使う場合

自作の WP_Query ループで表示する場合は、global $wp_query ではなくそのクエリのプロパティから値を取ります。

PHP:カスタムWP_Query版
$paged = max(1, get_query_var('paged'));

$my_query = new WP_Query(array(
  'category_name'  => 'news',
  'posts_per_page' => 10,
  'paged'          => $paged,
));

$total_posts    = (int) $my_query->found_posts;          // このクエリの総件数
$posts_per_page = (int) $my_query->get('posts_per_page'); // このクエリの表示件数

if ($total_posts > 0) {
  $start_num = ($paged - 1) * $posts_per_page + 1;
  $end_num   = min($paged * $posts_per_page, $total_posts);
  echo '全' . $total_posts . '件中 ' . $start_num . '件〜' . $end_num . '件目を表示';
}

一覧の各記事に「11.」「12.」と通し番号を振りたい場合は、ここで計算した $start_num と同じ考え方を使います。記事一覧に連番を振る方法(ページネーション対応)で詳しく解説しています。

よくある質問(FAQ)

Q最後のページかどうかを判定するには?
Aif ($paged >= $wp_query->max_num_pages) で判定できます($paged は1始まり・max_num_pages は総ページ数)。最終ページだけ「全ての記事を表示しました」のようなメッセージを出す使い方ができます。
Q投稿全体の件数(クエリと無関係な総数)を出すには?
Awp_count_posts()->publish で公開済み投稿の総数を取得できます。この記事の found_posts は「現在のクエリにマッチする件数」なので、検索やカテゴリ絞り込みに連動します。使い分けは記事の件数を取得・表示する方法を参照してください。
Q無限スクロールでも「全◯件中」を更新できますか?
Aできます。Ajaxのレスポンスに総件数(REST APIなら X-WP-Total ヘッダー)と読み込み済み件数を含め、JavaScriptで表示を書き換えます。無限スクロールの実装はAjaxを使った無限スクロールを実現する方法が参考になります。

まとめ

  • 3つの値pagedmax(1, ...))・posts_per_pagefound_posts
  • 計算:開始 = ($paged - 1) * $per_page + 1、終了 = min($paged * $per_page, $total)
  • 0件ガード必須:無いと「全0件中1件〜0件目」と壊れる
  • カスタムWP_Queryでは $my_query->found_posts を使う

0件時とカスタムクエリの2点を押さえれば、どの一覧でも正確な表示範囲を出せます。