pre_get_posts フックの使い方|説明・引数・注意点

説明

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 を使う

関連項目

WP_Query、is_main_query()、get_posts()

公式リファレンス:pre_get_posts | WordPress Developer Resources

コメント

タイトルとURLをコピーしました