WordPressでメインクエリの一部を保持しながら取得条件を変えたい

カスタム

WordPressでメインクエリを変更したい時、query_posts を使うことは公式からも非推奨とされています。
実際に query_posts はページ送りがうまくいかない、条件をリセットし忘れて他所で検索条件が変わってしまう…など、カスタマイズ時の使い方を誤ると問題が起こりやすい関数です。
なので、代わりに pre_get_posts を使いましょう。

今回はメインクエリを変更する際利用するアクションフック pre_get_posts について紹介します。

その前に…メインクエリとは?サブクエリとは?

今回変更したいメインクエリとはそのページに設定された基本的な検索条件のことを指します。
メインクエリの内容はURLと連動しています。
以下は表示設定を10件と設定したWordPressでのメインクエリ例です。

トップページ:記事を10件、投稿日時降順
アーカイブページ(カテゴリ:ニュース):カテゴリ:ニュースの記事10件、投稿日時降順
アーカイブページ(2018年12月):2018年12月の記事10件、投稿日時降順

サブクエリとは

サブクエリとは、ざっくり言うとメインクエリではないものです。
メインクエリはURLと連動した内容でしたが、サブクエリはそれとは関係のないクエリです。
例えば下記のようなものです。

・どのページでも表示させているサイドバーの新着記事一覧10件
・フッターで表示している「お知らせ」カテゴリの記事一覧5件

などなど。

関数名、クラス名で言えば get_posts 、WP_Queryがサブクエリを生成するものです。
メインクエリを変更せずに記事を条件指定で取得したい場合はこのどちらかを使います。

pre_get_posts を使ってメインクエリを変更する

それでは実際にメインクエリを変更する方法を紹介します。
pre_get_posts はアクションフックなので functions.php で操作します。
query_posts ではテーマテンプレート内に条件を記述していましたが、pre_get_posts はテーマテンプレートを呼び出す前の時点で検索条件を変更する仕様になります。

is_main_query() メインクエリであればTRUEを返します。
is_admin() 管理画面であればTRUEを返します。
is_front_page() フロントページであればTRUEを返します。
is_category() カテゴリページであればTRUEを返します。
is_tag() タグページであればTRUEを返します。
function edit_home_main_query( $query ) {
    if ( is_admin() OR !$query->is_main_query() ){
         return;
    }
	
	// トップページ
    if ( $query->is_home() ) {
        $query->set('posts_per_page', 5);
    }

	// カテゴリページ
    if ( $query->is_category() ) {
        $query->set('posts_per_page', 20);
    }

	// タグページ
    if ( $query->is_tag() ) {
        $query->set('posts_per_page', 20);
    }
}
add_action('pre_get_posts','edit_home_main_query');

functions.php は管理画面など至るところで使用されています。
管理画面以外のメインクエリにのみ反映させるため、上部で条件分岐させています。
ページ別に条件を変えたい場合は、is_home()、is_category() などの関数を利用しましょう。

$query->set に渡すパラメーターは WP_Query のものとほぼ同じです。

カスタム

関連記事