web-dev-qa-db-ja.com

カスタム投稿タイプで使用される分類用語を取得する

私はカスタム投稿タイプ - case - を持っており、そのために私はアーカイブページを作成しています。このタイプには3つのカスタム分類法があります - micro_organisms 感染タイプ 、および antibiotic_types 。これらの分類法は階層的で、最大3レベルまでのさまざまな用語があります。与えられた投稿タイプについて、たとえば antibiotic_types 分類法の用語をリストしたいと思います。これは case エントリで使用されます。

antibiotic_types 分類法内の用語は、 case エントリのどれでも使用できますが、選択した用語の階層を表示したいと思います。

これまでのところ、私は次のような作業を行ってきました。その結果、選択された用語のみのフラットリストが表示され、用語の階層は反映されません。

// sourced from:
// http://wordpress.stackexchange.com/questions/66015/how-to-get-a-list-of-taxonomy-terms-which-are-being-used-only-within-certain-pos
function get_terms_by_post_type( $taxonomies, $post_types ) {
    global $wpdb;
    $query = $wpdb->get_results( "SELECT t.*, COUNT(*) AS count from $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id WHERE p.post_type IN('" . join( "', '", $post_types ) . "') AND tt.taxonomy IN('" . join( "', '", $taxonomies ) . "') GROUP BY t.term_id");
    return $query;
}
?>
...
<ul class="taxonomy-term-list">
<?php
$terms = get_terms_by_post_type(array($tax), array('case'));

foreach ($terms as $term):
    $termData = get_term_by('id', $term->term_id, $tax);
    $termName = $termData->name;
    $termUrl = get_term_link($termData);
?>
    <li class="taxonomy-term"><a href="<?php echo $termUrl; ?>?post_type=<?php echo $type; ?>"><?php echo $termName; ?> (<?php echo $term->count; ?>)</a></li>
<?php
endforeach;
?>
</ul>

出力は次のようになります。

  • ペニシリン-g
  • セフトリアキソン
  • アムホテリシンb
  • 5-フルシトシン

望ましい出力は次のとおりです。

  • ベータラクタム
    • セファロスポリン
      • セフトリアキソン
    • ペニシリン
      • ペニシリン-g
  • 抗真菌剤
    • アムホテリシンb
    • 5-フルシトシン

私はまた以下を使ってみました:

wp_list_categories(
    array(
        'taxonomy' => 'antibiotic_types',
        'hierarchical' => 1,
        'hide_empty' => 1,
        'title_li' => ''
    )
);

これは与えられた分類法のためのallを示します、たとえ case エントリで使われていないものでも。

関数リファレンスを参照したので、直接ではなく、私が達成したいことを行うための組み込み関数があるかのようには見えません。私は今まで分類学上の質問をしていませんでした。助言がありますか?

1
Grant Palin

Codexに wp_list_categories のdocがある場合は、それがincludeパラメータを受け入れることに気付くでしょう。それはカテゴリIDのカンマ区切りリストを含むべきです。

そのため、関数get_terms_by_post_typeを変更して、関数get_terms_id_by_post_typeを作成し、用語idsのみを取得するようにします。

function get_terms_id_by_post_type( $taxonomies, $post_types ) {
    global $wpdb;
    $query = $wpdb->get_col( "SELECT t.term_id from $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id WHERE p.post_type IN('" . join( "', '", $post_types ) . "') AND tt.taxonomy IN('" . join( "', '", $taxonomies ) . "') GROUP BY t.term_id");
    return $query;
}

その後、次のことができます。

// retrieve the term ids used by post type
$terms = get_terms_id_by_post_type( array($tax), array('case') );

// if that terms exist implode in a commasepared string
$term_list = ! empty($terms) ? implode(',', $terms) : false;

// use wp_list_categories with include param to included only used terms
if ( $term_list ) {
  wp_list_categories(
    array(
        'taxonomy' => 'antibiotic_types',
        'hierarchical' => 1,
        'hide_empty' => 1,
        'title_li' => '',
        'include' => $term_list
    )
  );
}
4
gmazzap

他の誰かが、CPT投稿で使用されている1つの分類から別の分類に設定された用語のみを表示する必要がある場合に備えて、@ gmazzapによる回答に基づいて、そのために使用したコードです。

// Get all story post IDs set to story_type of "rn"
$story_post_ids = get_posts([
  'numberposts' => -1,
  'fields'      => 'ids',
  'post_type'   => 'story',
  'tax_query'   => [
    [
      'taxonomy' => 'story_type',
      'field'    => 'slug',
      'terms'    => ['rn'],
      'compare'  => 'IN',
    ]
  ],
]);

// Find story topics in use by those post IDs
$story_topic_ids = $wpdb->get_col("
      SELECT t.term_id FROM $wpdb->terms AS t
      INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id
      INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id
      WHERE tt.taxonomy IN('story_topic')
      AND r.object_id IN (".implode(',', $story_post_ids).")
      GROUP BY t.term_id
");

// Pull those topics
$story_topics = get_terms([
  'taxonomy' => 'story_topic',
  'include'  => $story_topic_ids,
]);

これにより、 "rn"という用語story_topicに設定された投稿で使用されているタイプstory_typeのすべての用語が検索されます。

0
natebeaty