WordPressのアーカイブページで表示件数を絞りページングさせない方法

nofoundrow01

WordPressのカテゴリページなどアーカイブページで「新着記事を5件だけ表示したい」「おすすめ商品5件だけ表示したい」「ページングしたくない」といった場合の方法です。

サブクエリでサイドバーに新着記事5件表示させる方法はよくありますが、これはメインクエリで行う方法です。メインコンテンツとして表示件数を絞り、ページングさせない方法です。

スポンサーリンク

やり方

functions.phpにpre_get_postというアクションフックを追加します。以下のコードです。

$query->set('posts_per_page', 10);  // 表示する件数
$query->set('no_found_rows', true); // ページング無効化

実際には、以下のように該当する条件にて使用してください。

function my_pre_get_posts() {
  // 管理画面とメインクエリ以外はフィルタの対象外とする
  if ( is_admin() || !$query->is_main_query() ) {
    return;
  }

  // 特定カテゴリの場合
  if ( is_category('10') ) {
    $query->set('posts_per_page', 5);  // 表示する件数
    $query->set('no_found_rows', true); // ページング無効化
    $query->set('orderby', array('post_date' => 'desc')); // 投稿日時の新しい順
  }
}
add_action( 'pre_get_posts', 'my_pre_get_posts' );

任意の条件下で任意のソート順を指定してください。

解説

WordPressはリクエストされたURLに応じて、自動的にデータベースから条件に合致する投稿を取得して表示します。

  • /categoryならカテゴリーアーカイブ
  • /post_nameなら投稿記事ページ

という具合に。

pre_get_postsはリクエストに応じてデータベースから取得する前に、データベースから取得する条件を変更するアクションフックです。

posts_per_pageとno_found_rowsについて

posts_per_pageとは1ページあたり表示する投稿件数を指定するオプションです。

no_found_rowsとはページング時に、全ページの合計投稿記事数を取得するためのオプションです。デフォルトでfalse(全ページの合計投稿記事数を取得する)に設定されています。つまり、ページングしない場合はtrueに設定する必要があります。

その他補足

さらに細かい部分についてふれます。興味のある方はご覧ください。

WP_Queryにnopagingというパラメータがあるけど?

WP_Queryのオプションにnopagingというページングさせるかどうかのパラメータがあります。

$query->set('posts_per_page', 5);  // 表示する件数
$query->set('nopaging', true); // ページング無効化

じゃダメなの?と私はなったのですが、実際には動きません。同時に指定した場合、nopagingが有効になり、posts_per_pageは無視されます。結果、1ページに全件表示されます。

posts_per_pageだけ指定してページネーション非表示にすれば?

posts_per_pageだけ指定して、ページネーションを隠せば同じことが実現できます。ただ、内部的には全件取得する処理が動いてるので無駄な処理が動くことになります。サイトへの負荷は少しでも減らした方がいいと思います。

no_found_rowsとは?

ページング時にトータル件数を取得する仕組みを動作させるオプションです。実際にはMySQLのSQL_CALC_FOUND_ROWSという仕組みが動作しています。これはページング時に全件数を取得するためときに便利な機能ですが、条件に合致するものが10万件あれば10万件内部的に取得しています。

件数が多ければ多いほど取得に時間がかかり、ページ表示速度に影響します。

本記事のようにページングなしで件数を絞る場合は不要な処理ですし、件数を絞らなくてもページングしないのであれば不要です。

単に該当ページでget_postsすればいいのでは?

サイドバーに新着記事5件表示する場合、get_postsでいいです。この場合、no_found_rowsは関係なく、posts_per_pageを指定すればいいです。

この方法はサブクエリと呼ばれる方法です。

アーカイブページでget_postsして出力しても同じ結果は得られますが、内部的にはメインクエリが必ず先に実行されているのでその処理が無駄になります。(データベースに2回問い合わせすることになる)

メインクエリ、サブクエリについてはいずれ記事にしたいと思います。

いつ使うの?

親カテゴリと子カテゴリで構成されている場合、親カテゴリのアーカイブでは特別な表示にしたいとき。例えば、親カテゴリではカテゴリ全体から新着記事を5件表示し、その他は子カテゴリへ誘導したいときなど。

まとめ

個人的にやりたかったことなのですが、ググっても出てきませんでした。誤りがあったり、もっといい方法があればコメントやTwitterなどで教えてくださいませ。

スポンサーリンク

この記事が気に入っていただけたらシェアお願いします。励みになります。
prev Googleタグマネージャでクリックイベントを計測する3つの方法

スポンサーリンク

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です