WordPressの投稿取得を自在に操れるpre_get_posts の便利な使い方まとめ
※本記事のコードは参考用です。使用前にご自身で動作確認をお願いします。
WordPress で投稿の一覧をカスタマイズしたいとき、非常に強力なのが pre_get_posts
フィルターフックです。
このフックを使えば、テーマのテンプレートをいじらなくても、投稿・カスタム投稿の取得条件を柔軟に変更することができます。
本記事では、pre_get_posts
の基本と、実際によく使われるカスタマイズ事例を一覧形式で紹介します。
pre_get_posts
とは
pre_get_posts
は WordPress が投稿を取得する「直前」に実行されるフックです。
このタイミングでクエリ(WP_Query
オブジェクト)を変更することで、投稿一覧に表示される内容を自在にコントロールできます。
pre_get_posts
の基本形
function my_query_customization( $query ) {
if ( is_admin() || ! $query->is_main_query() ) return;
// ここで条件を変更
}
add_action( 'pre_get_posts', 'my_query_customization' );
よく使われるカスタマイズ例
1. カスタム投稿タイプのアーカイブで表示件数を変更
個人的にpre_get_posts
で最もよく使うコードです。カスタム投稿タイプが複数存在し、各自の表示件数を変更するコードです。
以下のコードでは、eventというカスタム投稿タイプの表示件数を20件に設定しています。
if ( $query->is_post_type_archive( 'event' ) && $query->is_main_query() ) {
$query->set( 'posts_per_page', 20 );
}
2. トップページに特定のカテゴリーのみ表示
トップページでは投稿一覧に、newsカテゴリだけを表示したいときなどに便利です。
if ( ( $query->is_home() || $query->is_front_page() ) && $query->is_main_query() ) {
$query->set( 'category_name', 'news' );
}
3. カスタム投稿タイプをアーカイブに含める
通常投稿アーカイブに、例えばeventというカスタム投稿も表示したいときなどに利用できます。
if ( $query->is_archive() && $query->is_main_query() ) {
$query->set( 'post_type', array( 'post', 'event' ) );
}
4. タグ付き投稿を除外する(例:非表示タグ)
特定の投稿は一覧荷表示したくない場合、例えば「非公開」「非表示」などのタグをつけ、それを投稿を一覧に出さないようにするといったことも可能です。
if ( $query->is_main_query() && ! is_admin() ) {
$query->set( 'tag__not_in', array( 123 ) ); // 除外したいタグのID
}
5. 年別アーカイブを年度別に変更する
年別アーカイブは通常1月から12月の範囲ですが、4月から翌3月までに変更するコードです。学校・行政などの公的機関などでは要望が多いのではないでしょうか。
if ( $query->is_year() && $query->is_main_query() ) {
$y = get_query_var( 'year' );
$query->set( 'date_query', array(
array(
'after' => "$y-04-01 00:00:00",
'before' => ($y + 1) . "-03-31 23:59:59",
'inclusive' => true,
),
));
$query->set( 'year', null );
}
6. 特定の検索結果だけカスタマイズする
検索結果にカスタム投稿タイプを含めたり、件数を変えたりすることができます。
if ( $query->is_search() && $query->is_main_query() ) {
$query->set( 'posts_per_page', 50 );
$query->set( 'post_type', array( 'post', 'news' ) );
}
7. 特定のカスタムフィールド値で絞り込む
例えば、今日以降のイベントだけを表示したい場合などに便利です。
if ( $query->is_main_query() && is_post_type_archive( 'event' ) ) {
$query->set( 'meta_query', array(
array(
'key' => 'event_date',
'value' => date('Y-m-d'),
'compare' => '>=',
'type' => 'DATE'
)
));
}
注意点:is_main_query()
と ! is_admin()
を忘れずに
pre_get_posts
を使ってクエリをカスタマイズする場合、管理画面への影響を防ぐために is_admin()
を使うことが必須です。また、メインクエリだけを対象にするには is_main_query()
もセットで使いましょう。
if ( ! is_admin() && $query->is_main_query() ) {
// クエリのカスタマイズ
}
! is_admin()
:管理画面では何も変更しないようにする$query->is_main_query()
:メインクエリ(ループ)だけを対象にして、サブクエリ(ウィジェットなど)は無視
まとめ
pre_get_posts
を使えば、テンプレートファイルを複雑に書き換えることなく、投稿の取得条件を柔軟に変更できます。
特に一覧ページのカスタマイズや条件による出し分けが必要な場面では、非常に便利な仕組みです。