ヘッダーのロゴ

すぐに仕事で使えるIT技術情報メディア

すぐ使える!WordPressのpre_get_postsフックでメインクエリの記事一覧の表示件数を変更する方法

投稿日:2024年04月13日(土) 更新日:2024年04月18日(木)
すぐ使える!WordPressのpre_get_postsフックでメインクエリの記事一覧の表示件数を変更する方法|WordPress MAGAZINE ワードプレスマガジン|すぐに仕事で使えるIT技術情報メディア

みなさんこんにちは!エンジニアの高澤です!

今回はWordPressのpre_get_postsフックでメインクエリの記事一覧の表示件数を変更する方法について解説していきたいと思います。

今回の内容は、通常では管理画面でしか変更ができないメインクエリの記事一覧の表示件数を、WordPressのフックを使って変更することによって柔軟にWordPressの記事一覧の挙動をカスタマイズできるようになる内容になります。

これまでの経験上筆者的にはWordPress開発において実装することがほとんどなので、当記事は頻繁にお使いいただける内容になるかと思います。

よろしければぜひ当記事をお仕事でお役立ていただけましたら幸いです。

今回実装する内容

実装する方法を解説する前に、今回実装する内容についてご説明したいと思います。

通常、index.phpやcategory.phpなどのメインクエリで出力するWordPressであるメインループの表示件数は、デフォルトでは10件となっております。

この10件という件数は、下図の管理画面左メニューの「設定」の「表示設定」にある「1ページに表示する最大投稿数」で変更することが可能です。

ここで変更できるのはいいのですが、このままだとindex.phpやcategory.phpなどでの表示件数がすべて10件と同じになってしまい、それぞれのPHPテンプレートファイルごとに表示件数を変更することができません。

それを可能にするのが当記事の内容です。

当記事の内容を実装することによって、通常変更できないindex.phpやcategory.phpなどに表示されるメインクエリのメインループの表示件数をテンプレートごと、もしくはページごとで変更することが可能です。

実装する方法

それでは実装する方法を解説したいと思います。

以下のコードをfunctions.phpにコピー&ペーストしてください。

<?php
// カスタム条件を追加する関数
function my_posts_control( $query ) {
  // 管理画面の場合やメインクエリでない場合は何もしない
  if ( is_admin() || ! $query->is_main_query() ) {
    return;
  }
  // メインクエリに対するカスタム条件をここに記述
}
// pre_get_posts フィルターフックに関数を追加
add_action( 'pre_get_posts', 'my_posts_control' );

独自に定義したmy_posts_control()関数は、$queryパラメーターを受け取ります。

これは、WordPressのクエリオブジェクトであり、メインクエリに対してカスタム条件を追加するために使用されます。

is_admin()関数を使用して、現在のページが管理画面かどうかを確認します。もし管理画面であれば関数を終了します。

$query->is_main_query()を使用して、現在のクエリがメインクエリかどうかを確認します。もしメインクエリでなければ関数を終了します。

メインクエリに対するカスタム条件を追加する部分には、「// メインクエリに対するカスタム条件をここに記述」とコメントが入っており、ここに条件を記述します。具体的な条件は状況に応じてサイトに適した形で記述してください。

このようにして、pre_get_postsフィルターフックを使用して、メインクエリに対するカスタム条件を追加する関数を定義することができます。

カテゴリーアーカイブページで表示件数を5件にする場合

次は具体的な実装例として、カテゴリーアーカイブページで表示件数を5件にする実装方法について解説したいと思います。

以下のコードをfunctions.phpにコピー&ペーストしてください。

<?php
// カスタム条件を追加する関数
function my_posts_control( $query ) {
  // 管理画面の場合やメインクエリでない場合は何もしない
  if ( is_admin() || ! $query->is_main_query() ) {
    return;
  }
  // カテゴリーアーカイブページであれば
  if ( $query->is_category() ) {
    // 表示件数を5件に設定
    $query->set( 'posts_per_page', '5' );
    return;
  }
}
// pre_get_posts フィルターフックに関数を追加
add_action( 'pre_get_posts', 'my_posts_control' );

上記のコードは、カテゴリーアーカイブページ(category.php)のメインクエリに対して、表示件数を5件に設定するようにしています。

is_category()関数メソッドは、現在のページがカテゴリーアーカイブページかどうかを確認します。

カテゴリーアーカイブページの場合、set()メソッドを使用して、posts_per_page パラメーターを5に設定しています。これにより、カテゴリーアーカイブページで表示される投稿の件数が5件に制限されます。

このようにして、pre_get_posts フィルターフックを使用して、特定の条件に応じてメインクエリの結果を変更することができます。

カスタム投稿タイプのアーカイブページで制御する場合

次は、カスタム投稿タイプのアーカイブページで制御して実装する方法について解説したいと思います。

ここではカスタム投稿タイプ「custom_post_type」の記事ページに、カスタムフィールド「custom_field1」が設定されているものとします。

以下のコードをfunctions.phpにコピー&ペーストしてください。

<?php
// カスタム条件を追加する関数
function my_posts_control( $query ) {
  // 管理画面の場合やメインクエリでない場合は何もしない
  if ( is_admin() || ! $query->is_main_query() ) {
    return;
  }
  // カスタム投稿タイプ 'custom_post_type' のアーカイブページであれば
  if ( $query->is_post_type_archive( 'custom_post_type' ) ) {
    // 「custom_field1」のメタキーで昇順でソートするよう設定
    $query->set( 'orderby', 'meta_value' );
    $query->set( 'meta_key', 'custom_field1' );
    $query->set( 'order', 'ASC' );
    return;
  }
}
// pre_get_posts フィルターフックに関数を追加
add_action( 'pre_get_posts', 'my_posts_control' );

上記コードでは、特定の条件に応じてメインクエリの結果を変更しています。

$query->is_post_type_archive( 'custom_post_type' ) は、現在のページが 「custom_post_type」というカスタム投稿タイプのアーカイブページであるかどうかを確認します。

アーカイブページの場合、set()メソッドを使用して、orderbyを「meta_value」に、「meta_key」を「custom_field1」に、「order」を ASC (昇順) に設定しています。

これにより、「custom_field1」のメタキーで投稿が昇順に表示されます。

このようにして、pre_get_postsフィルターフックを使用して、特定の条件に応じてメインクエリの結果を変更することができます。

まとめ

WordPressのpre_get_postsフックでメインクエリの記事一覧の表示件数を変更する方法についての解説は以上になります。

今回の内容は、管理画面でしか変更ができないメインクエリの記事一覧の表示件数を、フックを使って変更することによって柔軟にWordPressの記事一覧の挙動をカスタマイズできるようになる内容になります。

これまでの経験上筆者的には当記事の内容は頻繁に実装する機会があるかと思いますので、必ず習得しておくべき内容といっても過言ではありません。

よろしければぜひ当記事をお仕事でお役立ていただけましたら幸いです。

執筆者

ワードプレスマガジン編集部 高澤 翔汰

歴4年目(2024年8月以降から5年目です)のエンジニアです!
CMSでのサイト構築とWebデザイン制作を兼任して4年目になります。
自作のiOSアプリ(iPhoneアプリ)やWordPressプラグインを開発することもあり、まだまだ現在進行形で勉強中です!