WordPressのメインループの内容を書き換える方法

WordPressのメインループのクエリをfunctions.phpから書き換える方法です。

一般的にはテンプレートを用意してWP_Queryで書き換えることが多いですが、そんな手間をかけなくてもサクッとfunctions.phpで書き換えることも可能なのです。

メインループという言葉自体が怪しい方は、まず以下の記事を事前に参考にしてください!(メインループはサブループの対になる言葉です)

WordPressの任意のループ(サブループ)を作る方法と覚えておきたい指定方法

はにわまん
テンプレート作らずにサクッと書き換えられるので好きです

メインクエリを書き換える方法

それではメインクエリをfunctions.phpから書き換えてみます。書き換えるには、pre_get_posts()というフィルターフックを使います。
プラグイン API/アクションフック一覧/pre get posts – WordPress Codex 日本語版

以下の例は、クエリの中のposts_per_pageを上書きして6にしています。これは「1ページあたりの表示件数を6件に変更する」とう指定になります。

functions.phpコピーfunction my_query( $query ) {

	$query->set( 'posts_per_page', '6' );
	return $query;
}
add_filter( 'pre_get_posts', 'my_query' );

10件の表示だったものが6件になりました!

setの中に対応しているのは、

  • 第一引数・・・WP_Queryで指定する時のパラメータ
  • 第二引数・・・WP_Queryで指定する時のパラメータに対する値

参考 → 関数リファレンス/WP Query – WordPress Codex 日本語版

書き換える基本が分かったところで、ありがちな書き換えのパターンを見ていきましょう!

ケース別のメインクエリ書き換える方法

ケース別のメインクエリの書き換えパターンです。基本的には特定の条件をifの条件分岐で制限して、その時だけ書き換えられるような動きにする形となります。

検索結果から固定ページは除外したい

if ( $query->is_search )で検索一覧かどうかを判定して、投稿タイプを「投稿」だけに書き換えています。

functions.phpコピーfunction my_query( $query ) {

	if ( $query->is_search ) {
		$query->set( 'post_type', 'post' );
	}
	return $query;
}
add_filter( 'pre_get_posts', 'my_query' );

検索結果に投稿タイプも含めたい

先ほどと似ていますが、他の投稿タイプを加えるパターンです。当たり前ですが投稿タイプも自由に選択できるということですね。配列のようにしていくつでも追加することができます。your-post-type-nameはご自身が追加した投稿タイプ名です。

functions.phpコピーfunction my_query( $query ) {

	if ( $query->is_search ) {
		$query->set( 'post_type', array( 'post', 'your-post-type-name' ) );
	}
	return $query;
}
add_filter( 'pre_get_posts', 'my_query' );

特定の投稿タイプ一覧だけ表示件数を変更したい

is_post_type_archiveで特定の投稿タイプの一覧を絞ることができます。

functions.phpコピーfunction my_query( $query ) {

	if ( is_post_type_archive( 'your-post-type-name' ) ) {
		$query->set( 'posts_per_page', 16 );
	}
	return $query;
}
add_filter( 'pre_get_posts', 'my_query' );

ちなみに、-1にすると、「制限なし」ですべての投稿が表示されるようになります。

複数の条件を書き換えたい

例として1つのパラメーターの値の書き換えしか行っていなかったので念のための紹介です。複数のパラメーターを書き換えたい場合は単純に2つ書けばOKです!

functions.phpコピーfunction my_query( $query ) {

	$query->set( 'post_type', 'post' );
	$query->set( 'posts_per_page', 16 );
	
	return $query;
}
add_filter( 'pre_get_posts', 'my_query' );

【重要】メインクエリ以外は変更しない設定

実は、こままだとオリジナルで作成したクエリにも影響が及んでしまいます。オリジナルとはWP_Query()で独自に作ったサブループと呼ばれるループです。

サブループについては以下で詳しく解説しています。

WordPressの任意のループ(サブループ)を作る方法と覚えておきたい指定方法

サブループは意図的に作っているので変更対象としてほしくないはずです。サブループを書き換え対象から除外するという記述を先頭に入れてあげると意図しない動きをさせずに済みます。
(個人的に過去にハマってめっちゃ悩みました…)

functions.phpコピーfunction my_query( $query ) {

	if ( ! $query->is_main_query() ) {
		return $query;
	}

	if ( $query->is_search ) {
		$query->set( 'post_type', array( 'post', 'your-post-type-name' ) );
	}
	return $query;
}
add_filter( 'pre_get_posts', 'my_query' );

$query->is_main_query()がメインループかどうかを判定しています。メインループでなければ、そのままのクエリを返すと言う処理ですね。

サブループの作り方と似ている

$query->set();の引数でメインループの書き換えを行っていますが、これはサブループを作る時のやり方とほとんど同じです。要するに、WP_QueryのCodexの記載されているループのクエリには作り変えられるということです。
関数リファレンス/WP Query – WordPress Codex 日本語版

サイトが複雑になってくると、「○○の条件では、ちょっとループを変えたい…」みたいなことが起きがちです。

メインループはpre_get_postsのフィルターから条件に応じてifで分けてあげれば作り直せることを覚えておけば、WordPressのカスタマイズの幅も広がっていくかと思います。

おわり

WordPressのメインループの内容をfunctions.phpから書き換える方法でした。

メインループを書き換えるたびにテンプレートを作成するのも手間ですので、functions.phpからサクッと書き換えられることを覚えておくと案件を進めるのが楽になるかもしれません。

このページが役に立ったら
いいね!お願いします

運営の励みになります...。

関連の記事