web-dev-qa-db-ja.com

WP_Queryが与えられたら、どうやってタグのリストを取得できますか?

私はカスタムループを生成し、投稿のセットを表示するために使用するnew WP_Queryを持っています。クエリが行うことの1つは、ページ付けを提供することです。

ただし、クエリされた投稿を表示する前に、見つかった投稿のすべてのタグのリストを取得したいと思います。各投稿をループ処理して重複を削除することでこれを実行できることはわかっていますが、もっとエレガントな方法を望んでいました。

3
Jack

それは可能だとは思わない。 WP_Queryによって実行されるSQLクエリはpostオブジェクト(そしておそらくいくつかのメタデータ)のみを返しますが、タグは別のテーブルにあります。テンプレートで返された投稿をループするとき、あなたは通常the_tags();か何か類似したものをあなたのテンプレートに入れます。それは順番にそれぞれの投稿に対して新しいデータベースクエリを実行します。

ただし、プライマリ投稿クエリを実行する前に別のクエリを実行してタグを読み込むこともできます。私が知っている限りでは、一度に複数の記事のタグをロードすることを可能にする関数WordPress APIはありませんが、$wpdbを直接呼び出すことによってそれを達成することができます。

このような何かはあなたが始めるのを助けるかもしれません:

global $wpdb;
$sql = $wpdb->prepare(
    "SELECT DISTINCT $wbdb->terms.* FROM $wbdb->term_relationships
        JOIN $wbdb->posts
            ON $wbdb->posts.ID = $wbdb->term_relationships.object_id
        JOIN $wbdb->term_taxonomy
            ON $wbdb->term_taxonomy.term_taxonomy_id = $wbdb->term_taxonomy.term_taxonomy_id
        JOIN $wbdb->terms
            ON $wbdb->term_taxonomy.term_id = $wbdb->terms.term_id
        WHERE $wbdb->term_taxonomy.taxonomy = 'post_tag'
            AND $wbdb->posts.ID IN (1,2,3,4,5,6,7,8,9,10)"
);
$tags = $wpdb->query($sql);

ご覧のとおり、これはあなたがあなたの投稿IDを事前に知っていることを前提としています。その場合、括弧内のリストをサブクエリに置き換える必要があります。サブクエリの最も単純な形式はSELECT ID FROM $wpdb->postsですが、カテゴリ、日付などで投稿をフィルタ処理/並べ替え/制限する必要があるでしょう。私のバージョンのMySQLはサブクエリでLIMITをサポートしていなかったこと。もしあなたのものもそうでなければ、1回の問い合わせでこれを達成するのは難しいかもしれません。たくさんの投稿がない限り、最初にWP_Queryをループして投稿IDを収集するだけです。いずれの場合も、投稿ごとにクエリを実行するのではなく、タグに関連するクエリを1つだけ実行するため、投稿ごとに個別のクエリを実行するよりも速くなります。

1
Simon

後世のために、私はただループを二度繰り返すことになりました:一度はタグを得て、そして次に実際にページを表示するために。

これが私のコードです:

if ( have_posts() ) :
 // get tags for found posts
 $recent_tags = array();
 while ( $loop->have_posts() ) : $loop->the_post();
  foreach(get_the_tags() as $t) $recent_tags[$t->slug] = $t->name; // this adds to the array in the form ['slug']=>'name'
 endwhile; 

 // de-dupe
 $recent_tags = array_unique($recent_tags);
 // sort
 natcasesort($recent_tags);

 // do something with the array

 while ( $loop->have_posts() ) : $loop->the_post();

 // normal wp loop
2
Jack

複数の投稿のタグを取得するには、'object_ids'get_terms() に渡すことで実現できます。

まず、別のWP_Queryが、あなたが望む投稿のIDのみを返すようにします。たとえば、特定のカテゴリのすべての投稿を取得します。

// Get the posts.
$category = get_queried_object();
$args = [
  'cat'    => $category->term_id,
  'fields' => 'ids',
];
$the_query = new WP_Query($args);

IDを取得したので、IDをget_terms()に渡すだけで、選択した投稿のすべてのタグのリストが返されます。

// Get the terms of these posts.
if ($the_query->have_posts()) {
  $terms = get_terms([
    'taxonomy' => 'post_tag',
    'object_ids' => $the_query->posts,
  ]);
}

出典: https://developer.wordpress.org/reference/classes/wp_term_query/__construct/#comment-2500

0
leymannx