私は2つのカスタム投稿タイプ 'bookmarks'と 'snippets'と共有分類法 'tag'を持っています。 get_terms()を使用すると、分類法に含まれるすべての用語の一覧を生成できますが、一覧を投稿の種類に限定する方法はわかりません。私が基本的に探しているのはこのようなものです。
get_terms(array('taxonomy' => 'tag', 'post_type' => 'snippet'));
これを達成する方法はありますか?アイデアは大歓迎です!
ああ、私はWP 3.1.1にいます
これは、1つのSQLクエリを使用して、同様のことをする別の方法です。
static public function get_terms_by_post_type( $taxonomies, $post_types ) {
global $wpdb;
$query = $wpdb->prepare(
"SELECT t.*, 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('%s') AND tt.taxonomy IN('%s')
GROUP BY t.term_id",
join( "', '", $post_types ),
join( "', '", $taxonomies )
);
$results = $wpdb->get_results( $query );
return $results;
}
だから私が取り組んでいるプロジェクトのためにそのようなものが必要になったのです。カスタムタイプのすべての投稿を選択するためのクエリを作成した後、それらが使用している分類の実際の用語が何であるかを確認します。
それから私はget_terms()
を使ってその分類学のすべての用語を得ました、そして次に私は両方のリストの中にあるものだけを使い、それを関数の中にまとめました。
しかし、それから私はもっとIDだけを必要としました:私は$fields
という名前の新しい引数を追加したので、関数に何を返すべきかを伝えることができました。それから私はget_terms
が多くの引数を受け入れ、私の関数はpost型で使用されている単なる用語に限定されていたので、もう一つif
ステートメントを追加してください。
/* get terms limited to post type
@ $taxonomies - (string|array) (required) The taxonomies to retrieve terms from.
@ $args - (string|array) all Possible Arguments of get_terms http://codex.wordpress.org/Function_Reference/get_terms
@ $post_type - (string|array) of post types to limit the terms to
@ $fields - (string) What to return (default all) accepts ID,name,all,get_terms.
if you want to use get_terms arguments then $fields must be set to 'get_terms'
*/
function get_terms_by_post_type($taxonomies,$args,$post_type,$fields = 'all'){
$args = array(
'post_type' => (array)$post_type,
'posts_per_page' => -1
);
$the_query = new WP_Query( $args );
$terms = array();
while ($the_query->have_posts()){
$the_query->the_post();
$curent_terms = wp_get_object_terms( $post->ID, $taxonomy);
foreach ($curent_terms as $t){
//avoid duplicates
if (!in_array($t,$terms)){
$terms[] = $c;
}
}
}
wp_reset_query();
//return array of term objects
if ($fields == "all")
return $terms;
//return array of term ID's
if ($fields == "ID"){
foreach ($terms as $t){
$re[] = $t->term_id;
}
return $re;
}
//return array of term names
if ($fields == "name"){
foreach ($terms as $t){
$re[] = $t->name;
}
return $re;
}
// get terms with get_terms arguments
if ($fields == "get_terms"){
$terms2 = get_terms( $taxonomies, $args );
foreach ($terms as $t){
if (in_array($t,$terms2)){
$re[] = $t;
}
}
return $re;
}
}
あなただけの用語IDのリストが必要な場合:
$terms = get_terms_by_post_type('tag','','snippet','ID');
用語名のリストだけが必要な場合は、
$terms = get_terms_by_post_type('tag','','snippet','name');
用語オブジェクトのリストだけが必要な場合は、次のようにします。
$terms = get_terms_by_post_type('tag','','snippet');
そして、あなたがのようなget_termsの追加の引数を使用する必要があるなら:orderby、order、hierarchy ...
$args = array('orderby' => 'count', 'order' => 'DESC', 'hide_empty' => 1);
$terms = get_terms_by_post_type('tag',$args,'snippet','get_terms');
楽しい!
更新:
期間数を特定の投稿タイプの変更に修正するには、次の手順を実行します。
foreach ($current_terms as $t){
//avoid duplicates
if (!in_array($t,$terms)){
$terms[] = $t;
}
}
に:
foreach ($current_terms as $t){
//avoid duplicates
if (!in_array($t,$terms)){
$t->count = 1;
$terms[] = $t;
}else{
$key = array_search($t, $terms);
$terms[$key]->count = $terms[$key]->count + 1;
}
}
post_type
配列の$args
をget_terms()
関数に渡すことを可能にする関数を書きました。
SQLを書くための@braydonへのHT。
/**
* terms_clauses
*
* filter the terms clauses
*
* @param $clauses array
* @param $taxonomy string
* @param $args array
* @return array
**/
function terms_clauses($clauses, $taxonomy, $args)
{
global $wpdb;
if ($args['post_type'])
{
$clauses['join'] .= " 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";
$clauses['where'] .= " AND p.post_type='{$args['post_type']}'";
}
return $clauses;
}
add_filter('terms_clauses', 'terms_clauses', 10, 3);
素晴らしい質問としっかりした答え。
@jessicaがterms_clausesフィルタを使用する方法は、get_terms関数を非常に合理的な方法で拡張するため、非常に気に入っています。
私のコードは、重複を減らすために@braydonからいくつかのSQLで、彼女のアイデアの続きです。 post_typeの配列も可能です。
/**
* my_terms_clauses
*
* filter the terms clauses
*
* @param $clauses array
* @param $taxonomy string
* @param $args array
* @return array
**/
function my_terms_clauses($clauses, $taxonomy, $args)
{
global $wpdb;
if ($args['post_types'])
{
$post_types = $args['post_types'];
// allow for arrays
if ( is_array($args['post_types']) ) {
$post_types = implode("','", $args['post_types']);
}
$clauses['join'] .= " 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";
$clauses['where'] .= " AND p.post_type IN ('". esc_sql( $post_types ). "') GROUP BY t.term_id";
}
return $clauses;
}
add_filter('terms_clauses', 'my_terms_clauses', 99999, 3);
Get_termsにはGROUPY BYの句がないため、WHERE句の末尾に追加する必要がありました。フィルタの優先順位が非常に高く設定されていることに注意してください。これが常に最後になることを願います。
Get_terms引数をGavinの上記のバージョンのコードと連携させることはできませんでしたが、最終的には
$terms2 = get_terms( $taxonomy );
に
$terms2 = get_terms( $taxonomy, $args );
それはBainternetからの元の機能にあったように。
@ベイターネット:ありがとう!機能していなかったので、機能を少し変更する必要がありました(いくつかのタイプミス)。現在の唯一の問題は、期間カウントがオフになっていることです。この数では投稿タイプを考慮に入れていないので、ここでget_terms()を使用できるとは思わない.
function get_terms_by_post_type($post_type,$taxonomy,$fields='all',$args){
$q_args = array(
'post_type' => (array)$post_type,
'posts_per_page' => -1
);
$the_query = new WP_Query( $q_args );
$terms = array();
while ($the_query->have_posts()) { $the_query->the_post();
global $post;
$current_terms = get_the_terms( $post->ID, $taxonomy);
foreach ($current_terms as $t){
//avoid duplicates
if (!in_array($t,$terms)){
$t->count = 1;
$terms[] = $t;
}else{
$key = array_search($t, $terms);
$terms[$key]->count = $terms[$key]->count + 1;
}
}
}
wp_reset_query();
//return array of term objects
if ($fields == "all")
return $terms;
//return array of term ID's
if ($fields == "ID"){
foreach ($terms as $t){
$re[] = $t->term_id;
}
return $re;
}
//return array of term names
if ($fields == "name"){
foreach ($terms as $t){
$re[] = $t->name;
}
return $re;
}
// get terms with get_terms arguments
if ($fields == "get_terms"){
$terms2 = get_terms( $taxonomy, $args );
foreach ($terms as $t){
if (in_array($t,$terms2)){
$re[] = $t;
}
}
return $re;
}
}
編集:修正を追加しました。しかし、どういうわけかそれはまだ私のために働いていません。カウントはまだ不正確な値を示しています。
重複を避ける:
//avoid duplicates
$mivalor=$t->term_id;
$arr=array_filter($terms, function ($item) use ($mivalor) {return isset($item->term_id) && $item->term_id == $mivalor;});
if (empty($arr)){
$t->count=1;
$terms[] = $t;
}else{
$key = array_search($t, $terms);
$terms[$key]->count = $terms[$key]->count + 1;
}