WordPressのメインループのクエリをfunctions.phpから書き換える方法です。
一般的にはテンプレートを用意してWP_Query
で書き換えることが多いですが、そんな手間をかけなくてもサクッとfunctions.phpで書き換えることも可能なのです。
メインループという言葉自体が怪しい方は、まず以下の記事を事前に参考にしてください!(メインループはサブループの対になる言葉です)
https://haniwaman.com/loop/
テンプレート作らずにサクッと書き換えられるので好きです
メインクエリを書き換える方法
それではメインクエリをfunctions.phpから書き換えてみます。書き換えるには、pre_get_posts()
というフィルターフックを使います。
→ プラグイン API/アクションフック一覧/pre get posts – WordPress Codex 日本語版
以下の例は、クエリの中のposts_per_page
を上書きして6にしています。これは「1ページあたりの表示件数を6件に変更する」とう指定になります。
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 )
で検索一覧かどうかを判定して、投稿タイプを「投稿」だけに書き換えています。
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
はご自身が追加した投稿タイプ名です。
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
で特定の投稿タイプの一覧を絞ることができます。
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です!
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()
で独自に作ったサブループと呼ばれるループです。
サブループについては以下で詳しく解説しています。
https://haniwaman.com/loop/
サブループは意図的に作っているので変更対象としてほしくないはずです。サブループを書き換え対象から除外するという記述を先頭に入れてあげると意図しない動きをさせずに済みます。
(個人的に過去にハマってめっちゃ悩みました…)
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からサクッと書き換えられることを覚えておくと案件を進めるのが楽になるかもしれません。