【WordPress】カスタム分類ではcategory__inが効かない

5,130views
wp_queryでカスタム分類をソートする方法

今表示している投稿と同じカテゴリーに属する投稿に絞って関連記事一覧を表示したい時、WP_Queryのパラメータでカテゴリーを指定してリクエストします。

今回は'category__in'では対応できないカスタム分類ではどのようにパラメータを指定するか紹介します。

一般的なカテゴリーでは'category__in'

ここで一般的なカテゴリーの指定方法として、表示中の投稿のカテゴリーID全てを配列に代入して、'category__in'に代入する方法があります。

<?php
$cats = get_the_category();
$cat_id = array();
foreach( $cats as $cat ){
  array_push( $cat_id,$cat->cat_ID );
}
$args = array(
  'category__in' => $cat_id,
  ...
  ...
}

$query = new WP_Query( $args );
while( $query->have_posts() ): $query->the_post();
...
...
...
endwhile;
?>

一般的には上のように指定します。

カテゴリーIDではなくカテゴリー名(スラッグ)で指定したい場合は'category__in'の代わりに'category_name'を使用します。

'category__in'では配列で指定したカテゴリーの1つでも含まれる投稿をリクエストするのに対し、表示中の投稿のカテゴリー全てに属する投稿をリクエストする場合は'category__in'の代わりに'category__and'を使用します。

ここで'category__in'と'category__and'のアンダースコア(アンダーバー)は2つで'category_name'はアンダースコア1つであることに注意してください。

カスタム分類では'tax_query'

独自にカスタム投稿タイプを設定した時、カスタム分類も同時に設定する場合が多いです。このカスタム分類で設定したカテゴリーをパラメータに指定する場合は上記の'category__in'や'category_name'を使用できません。それらは既存のカテゴリーに含まれるカテゴリーからしかソートすることができないことが原因となります。

カスタム分類を使用した投稿の関連投稿をソートするためには'tax_query'を使用します。'tax_query'は任意のタクソノミーに関連付けられた投稿をソートできるパラメータで、配列で代入するため複数のタクソノミーを指定することも可能です。

また、'tax_query'でカテゴリーIDを'terms'に配列を代入しますが、カスタム分類ではカテゴリーIDの配列変数の作り方も通常のカテゴリーと少し異なるので注意します。

カスタム投稿タイプが'blog'、カスタムタクソノミーが'blog_cat'のときの例を紹介します。

<?php
$cats = get_the_terms( $post->ID,'blog_cat' );//ここで$postはメインループで指定している変数によって異なる場合があります。
$cat_id = array();
foreach( $cats as $cat ){
  array_push( $cat_id, $cat->term_id );
}
$args = array(
  'post_type' => 'blog',
  'tax_query' => array(
    array(
      'taxonomy' => 'blog_cat',
      'terms' => $cat_id
    )
  )
);
//....以下略...
?>

これでカスタムタクソノミーに対応したカテゴリー絞り込みができるようになりました。

'tax_query'の配列の中の配列に'operator' =>' AND'パラメータを追加することによって'category__and'と同じような動きに変更することもできます。

同様に'field' => 'name'パラメータを追加することによって'category_name'と同じ動きをさせることもできます。

tax_queryの使い方

WP_Queryの記事取得でカスタムタクソノミーを指定して絞り込むためにはtax_queryを使うことがわかりました。

tax_queryはあらゆる絞り込みを想定されているのでいくつか使い方のサンプルを作っていきます。

前提条件

ご飯カテゴリー — タクソノミー名:food

  • 寿司 —— slug: sushi —— ID: 4
  • 焼肉 —— slug: yakiniku —— ID: 5
  • ラーメン —— slug: ra-men —— ID: 6

国カテゴリー — タクソノミー名:country

  • 日本 —— slug: japan —— ID: 7
  • アメリカ —— slug: us —— ID: 8
  • 中国 —— slug: china —— ID: 9

このようなカスタムタクソノミーがあるとします。

複数のID全て含むもの

<?php
  ...

  $args = array(
    ...
    'tax_query' => array(
      array(
         'taxonomy' => 'food',
         'terms' => array(4, 5),
         'operator' => 'AND'
      )
    )
  );

  ...
?>

これでご飯カテゴリーの”寿司”と”焼肉”のカテゴリーを持ってる投稿を表示することができます。

'operator'のデフォルトは'IN'です。'IN'の場合は指定したカテゴリーのどれかを持っている投稿の全てを表示します。

カテゴリーのスラッグで絞り込み

<?php
  ...

  $args = array(
    ...
    'tax_query' => array(
      array(
         'taxonomy' => 'food',
         'field' => 'slug',
         'terms' => 'ra-men'
      )
    )
  );

  ...
?>

'field'に'slug'と指定することで'terms'にスラッグを指定できるようになります。

'field'の初期値は'term_id'でこれは1つ目の例のようにカテゴリーIDで絞り込みをするときのパラメータです。

複数のカテゴリーで絞り込み

<?php
  ...

  $args = array(
    ...
    'tax_query' => array(
      'relation' => 'AND',
      array(
         'taxonomy' => 'food',
         'field' => 'slug',
         'terms' => 'sushi'
      ),
      array(
         'taxonomy' => 'country',
         'field' => 'slug',
         'terms' => 'Japan'
      )
    )
  );

  ...
?>

これで複数のカスタムタクソノミーを持っている投稿をそれぞれ指定したカテゴリーで絞り込むことができます。

まとめ

今回はカスタムタクソノミーのカテゴリーで投稿を絞り込む方法を紹介しました。

カスタムタクソノミーなのに'category__in'を使って効かないという状況は、'tax_query'を知っていてもたまにやってしまいます。

'tax_query'の使い方も忘れがちなので、個人的な備忘録になりました。

カテゴリー