WordPressのクエリを正しく扱う ― pre_get_postsの仕組みと使い分け
Masaki Oba
代表取締役・WordPress運用スペシャリスト
目次
WordPressのクエリを正しく扱う ― pre_get_postsの仕組みと使い分け
メインクエリとサブクエリ
WordPressのクエリを理解するには、まず「メインクエリ」と「サブクエリ」の違いを知っておく必要があります。
メインクエリ
WordPressはURLに応じて、表示に必要な投稿データを自動的にデータベースから取得します。この自動的な問い合わせがメインクエリです。
たとえば投稿の詳細ページにアクセスすると、メインクエリにはその記事のデータが格納されます。アーカイブページなら、該当する投稿の一覧が格納されます。テンプレート内でおなじみの have_posts() / the_post() のループは、このメインクエリのデータを出力しています。
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// 記事の出力処理
}
}
サブクエリ
メインクエリとは別に、任意の条件で投稿を取得したい場合に使うのがサブクエリです。サイドバーに「最新の5件」を表示したり、記事下に「関連記事」を出したりする場面で使います。サブクエリには WP_Query を使います(後述)。
query_postsが非推奨とされる理由
古いチュートリアルやレガシーなテーマでは、メインクエリのカスタマイズに query_posts() が使われていることがあります。
// 非推奨な書き方
query_posts( 'cat=1' );
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// ...
}
}
query_posts() には以下の問題があります。
- メインクエリを直接上書きするため、ページネーションが壊れたり、他のテンプレート処理に影響が出る
- 上書き前のクエリが失われるため、
wp_reset_query()を呼び忘れると予期しないバグが起きる - WordPress公式ドキュメントでも「この関数は使うべきではない」と明記されている
既存コードで query_posts() を見かけたら、pre_get_posts への置き換えを検討してください。
pre_get_postsの仕組みと基本の書き方
pre_get_posts は、メインクエリがデータベースに問い合わせる直前にフックして、クエリの条件を書き換えるアクションフックです。メインクエリを上書きするのではなく、実行前に条件を差し替えるため、安全にカスタマイズできます。
functions.php に記述します。
function my_customize_main_query( $query ) {
// 管理画面とメインクエリ以外には影響させない
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
// ここにカスタマイズ条件を書く
}
add_action( 'pre_get_posts', 'my_customize_main_query' );
最初の if 文は必ず入れてください。pre_get_posts は管理画面のクエリやサブクエリにも発火するため、この条件がないと意図しない箇所に影響が出ます。
実践的な使用例
アーカイブページの表示件数を変更する
function my_customize_main_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_archive() ) {
$query->set( 'posts_per_page', 12 );
}
}
add_action( 'pre_get_posts', 'my_customize_main_query' );
カスタム投稿タイプをカスタムフィールドで並び替える
イベント一覧を開催日の昇順で表示する例です。
function my_customize_main_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_post_type_archive( 'event' ) ) {
$query->set( 'orderby', 'meta_value' );
$query->set( 'meta_key', 'event_date' );
$query->set( 'order', 'ASC' );
}
}
add_action( 'pre_get_posts', 'my_customize_main_query' );
検索結果から固定ページを除外する
function my_customize_main_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_search() ) {
$query->set( 'post_type', 'post' );
}
}
add_action( 'pre_get_posts', 'my_customize_main_query' );
特定カテゴリーをトップページの一覧から除外する
function my_customize_main_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_home() ) {
$query->set( 'category__not_in', [ 5 ] );
}
}
add_action( 'pre_get_posts', 'my_customize_main_query' );
pre_get_postsとWP_Queryの使い分け
どちらもクエリを扱う仕組みですが、役割が明確に異なります。
| pre_get_posts | WP_Query | |
|---|---|---|
| 用途 | メインクエリの条件変更 | サブクエリの作成 |
| 記述場所 | functions.php | テンプレートファイル |
| 対象 | メインループの出力内容 | メインループ以外の投稿取得 |
pre_get_postsを使う場面
- アーカイブページの表示件数や並び順を変えたい
- 検索結果の対象を絞りたい
- トップページの投稿一覧の条件を変えたい
→ そのページが本来表示するデータの条件を変えたいとき
WP_Queryを使う場面
- サイドバーに最新記事を出したい
- 記事下に関連記事を表示したい
- トップページに特定カテゴリーの記事を並べたい
→ メインの表示とは別に、追加で投稿を取得したいとき
// WP_Queryの例: 最新の関連記事を3件取得
$related = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 3,
'category__in' => [ $current_category_id ],
'post__not_in' => [ get_the_ID() ],
]);
if ( $related->have_posts() ) {
while ( $related->have_posts() ) {
$related->the_post();
// 関連記事の出力処理
}
wp_reset_postdata();
}
WP_Query を使ったあとは wp_reset_postdata() を忘れずに呼んでください。メインクエリのグローバル変数($post など)を元に戻すために必要です。
よくあるミス
is_main_query() のチェック漏れ
pre_get_posts のコールバックで is_main_query() を確認していないと、ウィジェットやプラグインが内部で発行するサブクエリにまで影響が出ます。
is_home() と is_front_page() の混同
is_home(): 投稿一覧ページ(「表示設定」で指定した投稿ページ)is_front_page(): サイトのフロントページ
固定ページをフロントページに設定している場合、is_home() はフロントページでは false になります。条件分岐を間違えると「条件が効かない」というハマりどころになります。
関連記事
WordPressのパーマリンクをコードでカスタマイズする方法
WordPressのパーマリンク(URL構造)を管理画面の設定だけでなく、コードで柔軟にカスタマイズする方法を解説します。投稿タイプ別のURLプレフィックス追加やカスタム投稿タイプのスラッグ変更など、実務でよくあるケースをコード例とともに紹介します。
WebサイトにWordPressを導入すべきかどうかを決めるポイント
WordPressの導入を検討している企業や個人事業主向けに、その必要性を判断するためのポイントを解説します。更新頻度、セキュリティリスク、運用コストなどを踏まえ、WordPress以外の選択肢もあわせて紹介します。
サーバー選びでお悩みですか?ビジネスで利用するならエックスサーバービジネスがおすすめ
ビジネス利用に最適なレンタルサーバー選びのポイントを解説。運用実績、安定性、価格、サポート、SSLの5つの観点と、実際に業務で使っている立場からエックスサーバービジネスをおすすめする理由を紹介します。