WordPressで「複数のカテゴリー(ターム)に関係する記事をまとめて表示したい」というとき、WP_Query の tax_query を使います。ポイントは「いずれかに属する(OR)」なのか「すべてに属する(AND)」なのかをはっきりさせることと、タクソノミーとタームを混同しないことです。
まず用語を整理
- タクソノミー=分類の種類(例:
category、post_tag、独自のgenre) - ターム=その中の項目(例:category の「ニュース」「スポーツ」)
tax_queryではtaxonomyにタクソノミー、termsにターム(スラッグやID)を渡します
いずれかに属する記事を取得する(OR)
「ニュースまたはスポーツ」のようにどれかに当てはまれば表示したい場合は、1つの条件配列に複数のタームをまとめて渡すだけです。(同じタクソノミー内でのORは、これがいちばんシンプルで確実です。)
WP_Query:ニュース または スポーツ の記事(OR)
$args = array(
'post_type' => 'post', // 対象の投稿タイプに置き換える
'tax_query' => array(
array(
'taxonomy' => 'category', // タクソノミー
'field' => 'slug',
'terms' => array('news', 'sports'), // 複数タームをまとめて指定=OR
),
),
);
$the_query = new WP_Query($args);
if ($the_query->have_posts()) :
while ($the_query->have_posts()) : $the_query->the_post();
the_title('<h3>', '</h3>'); // the_title() は自動で出力する(echoは不要)
endwhile;
wp_reset_postdata(); // new WP_Query の後は wp_reset_postdata()
endif;
echo the_title() と wp_reset_query() は誤り
the_title() はそれ自体が出力する関数なので、echo the_title() は不要です(値を受け取りたいときは echo get_the_title();)。また、new WP_Query() のループ後は wp_reset_postdata() を使います(wp_reset_query() は query_posts() 用で、ここでは不適切です)。すべてに属する記事を取得する(AND)
「ニュースかつおすすめ」のように両方に当てはまる記事だけを出したい場合は、条件配列を分け、relation を AND にします。異なるタクソノミーをまたいで絞り込むときもこの形です。
WP_Query:カテゴリ「news」かつ タグ「featured」(AND)
$args = array(
'post_type' => 'post',
'tax_query' => array(
'relation' => 'AND', // すべての条件を満たす
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array('news'),
),
array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => array('featured'),
),
),
);
$the_query = new WP_Query($args);
OR と AND の使い分け
OR=どれかに属していれば表示(対象を広げる)。同一タクソノミー内なら1つの配列に複数タームでOK。
AND=すべてに属していれば表示(対象を絞る)。条件を配列で分け
OR=どれかに属していれば表示(対象を広げる)。同一タクソノミー内なら1つの配列に複数タームでOK。
AND=すべてに属していれば表示(対象を絞る)。条件を配列で分け
relation => 'AND'。AND・OR・NOT を組み合わせた複雑な条件はWP_Queryで複雑な条件検索を実装する方法で詳しく解説しています。アーカイブページ自体に反映するには pre_get_posts
上のコードは別に作るサブループです。「タクソノミー一覧ページ(アーカイブ)そのものに、関連タームの記事も含めたい」場合は、テンプレートで new WP_Query() を作るのではなく、pre_get_posts でメインクエリを変更します。これならページネーションも正しく動きます。
functions.php:カテゴリーアーカイブに関連タームも含める
add_action('pre_get_posts', function ($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
// 「news」カテゴリーのアーカイブに「sports」の記事も含める例
if ($query->is_category('news')) {
$query->set('category_name', 'news,sports'); // カンマ区切りで OR
}
});
アーカイブのメインクエリを変更する考え方はプラグインなしでページネーションを実装する方法の「404対策」や、検索結果を高速化するカスタムクエリ最適化術(meta_query・tax_queryの使い分け)も参考になります。
よくある質問(FAQ)
Qカスタムタクソノミーとカテゴリーを組み合わせて絞り込むには?
A
tax_query に relation => 'AND' を指定し、カテゴリーの条件とカスタムタクソノミーの条件を別の配列で並べます。両方を満たす記事だけが取得できます。IDで指定するなら field は省略(既定 term_id)、スラッグなら 'field' => 'slug' にします。Qタクソノミーのターム一覧を表示するには?
A
get_terms(array('taxonomy' => 'my_taxonomy', 'hide_empty' => false)) で取得します。各タームには name・slug・term_id・count があります。カテゴリー取得全般は記事のカテゴリーを取得する方法(完全ガイド)を参照してください。Q特定カテゴリーの記事が持つ別タクソノミーのタームだけ表示するには?
A対象記事を
WP_Query で取得し、各記事に wp_get_object_terms($post_id, '別タクソノミー') を適用してタームを集め、term_id で重複を除いてから表示します。まとめ
- OR(いずれか):1つの条件配列に
'terms' => array('news', 'sports') - AND(すべて):条件を配列で分け
'relation' => 'AND' - 用語:
taxonomyは分類の種類、termsは項目(混同しない) - アーカイブ自体を変えるなら
pre_get_posts(サブループのnew WP_Queryではない) - 後片付け:
the_title()はそのまま/wp_reset_postdata()でリセット
「OR で広げる/AND で絞る」を意識し、タクソノミーとタームを取り違えなければ、複数条件の記事一覧は正確に作れます。

