説明
pre_get_posts は、クエリが実行される直前に、クエリの条件を変更できるアクションです。メインクエリの絞り込みや件数変更に使います。
基本構文
do_action_ref_array( 'pre_get_posts', array( &$query ) )
引数
$query:WP_Queryオブジェクト(参照渡し)
戻り値
コールバックは $query を受け取ります。値を返す必要はありません。
使い方(サンプル)
add_action( 'pre_get_posts', function( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
$query->set( 'posts_per_page', 5 );
}
} );
注意点
is_admin()と$query->is_main_query()で、対象を必ず絞ります。- 条件判定には、グローバルの
is_home()ではなく$query->is_home()を使う方が確実です。 query_posts()の代わりに、この方法が推奨されます。
実務での使いどころ
- アーカイブページの表示件数や、並び順を変えるとき。
- 検索結果の対象を、特定の投稿タイプに絞るとき。
- 特定のカテゴリーを、トップページの一覧から除外するとき。
よくあるミスと対処
is_admin()と$query->is_main_query()の判定を入れていない。管理画面や、サブクエリまで書き換わります。- 対象のページを絞っていない。サイトのすべての一覧に、影響します。
- 条件分岐に、
$query->is_home()のような$queryのメソッドを使っていない。 - テンプレートの中で、
query_posts()を使っている。メインクエリを書き換えたいときは、このフックを使います。
NG例
add_action( 'pre_get_posts', function ( $query ) {
$query->set( 'posts_per_page', 3 ); // すべてのクエリが、3件になる
} );
OK例
add_action( 'pre_get_posts', function ( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_post_type_archive( 'news' ) ) {
$query->set( 'posts_per_page', 10 );
}
} );
使い分け早見表
| やりたいこと | 使うもの |
|---|---|
| そのページの一覧の条件を変える | pre_get_posts フック |
| 別枠の一覧を、ループで出す | WP_Query |
| 投稿の配列だけが欲しい | get_posts() |
| メインクエリを上書きする | query_posts() は使わず、pre_get_posts を使う |

コメント