get_terms nach benutzerdefiniertem Post-Typ

Ich habe zwei benutzerdefinierte Post-Typen ‘Land’ und ‘Stadt’ und eine gemeinsame Taxonomie ‘Flagge’.

Wenn ich verwende:

<?php $flags = get_terms('flag', 'orderby=name&hide_empty=0'); 

Ich bekomme eine Liste aller Begriffe in der Taxonomie, aber ich möchte die Liste auf den Beitragstyp ‘Land’ beschränken.

Wie kann ich es tun?


Verwenden der neuen Lösung

  0,'hide_empty' => 1,'post_types' =>array('country'))); foreach ($flags as $flag) { $childTerms = wpse57444_get_terms('flags',array('parent' => $flag->term_id,'hide_empty' => 1,'post_types' =>array('country'))); foreach ($childTerms as $childTerm) { echo $childTerm->name.'
'; } } ?>

Ich kann nicht $ childTerm-> name zurückgeben. Warum?

Solutions Collecting From Web of "get_terms nach benutzerdefiniertem Post-Typ"

Ich fürchte, das ist nativ (noch?) Nicht möglich. Sehen Sie diesen Trac: http://core.trac.wordpress.org/ticket/18106

Ähnlich verhält es sich auf der Taxonomie-Admin-Seite. Die Anzahl der Posts spiegelt alle Post-Typen wider. ( Ich bin mir ziemlich sicher, dass es dafür auch ein Trac-Ticket gibt ) http://core.trac.wordpress.org/ticket/14084

Siehe auch diesen verwandten Artikel .


Neue Lösung

Nachdem ich den unten stehenden Artikel geschrieben habe, habe ich einen viel besseren Weg gefunden (alter in dem Sinne, dass Sie mehr tun können), die Filter zu benutzen, die im get_terms() Aufruf zur Verfügung gestellt werden. Sie können eine Wrapper-function erstellen, die get_terms und (bedingt) einen Filter hinzufügt, um die SQL-Abfrage zu get_terms (um sie nach dem Post-Typ zu beschränken).

Die function verwendet dieselben Argumente wie get_terms($taxonomies, $args) . $args nimmt das zusätzliche Argument von post_types das ein Array |

Aber ich kann nicht garantieren, dass alles “wie erwartet” funktioniert (ich denke daran, die Anzahl aufzustocken). Es scheint zu funktionieren, indem Sie einfach die $args get_terms für get_terms .

 function wpse57444_get_terms($taxonomies, $args=array() ){ //Parse $args in case its a query string. $args = wp_parse_args($args); if( !empty($args['post_types']) ){ $args['post_types'] = (array) $args['post_types']; add_filter( 'terms_clauses','wpse_filter_terms_by_cpt',10,3); function wpse_filter_terms_by_cpt( $pieces, $tax, $args){ global $wpdb; //Don't use db count $pieces['fields'] .=", COUNT(*) " ; //Join extra tables to restrict by post type. $pieces['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 "; //Restrict by post type and Group by term_id for COUNTing. $post_types_str = implode(',',$args['post_types']); $pieces['where'].= $wpdb->prepare(" AND p.post_type IN(%s) GROUP BY t.term_id", $post_types_str); remove_filter( current_filter(), __FUNCTION__ ) return $pieces; } }//endif post_types set return get_terms($taxonomies, $args); } 

Verwendung

  $args =array( 'hide_empty' => 0, 'post_types' =>array('country','city'), ); $terms = wpse57444_get_terms('flag',$args); 

Original Work-around

Inspiriert von der oben genannten Trac-Ticket, (getestet, und es funktioniert für mich)

 function wpse57444_filter_terms_by_cpt($taxonomy, $post_types=array() ){ global $wpdb; $post_types=(array) $post_types; $key = 'wpse_terms'.md5($taxonomy.serialize($post_types)); $results = wp_cache_get($key); if ( false === $results ) { $where =" WHERE 1=1"; if( !empty($post_types) ){ $post_types_str = implode(',',$post_types); $where.= $wpdb->prepare(" AND p.post_type IN(%s)", $post_types_str); } $where .= $wpdb->prepare(" AND tt.taxonomy = %s",$taxonomy); $query = " 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 GROUP BY t.term_id"; $results = $wpdb->get_results( $query ); wp_cache_set( $key, $results ); } return $results; } 

Verwendung

  $terms = wpse57444_filter_terms_by_cpt('flag',array('country','city')); 

oder

  $terms = wpse57444_filter_terms_by_cpt('flag','country'); 

@ Stephen-Harris ‘obige Antwort hat nur teilweise für mich funktioniert. Wenn ich versuchte, es zweimal auf der Seite zu verwenden, funktionierte es nicht. Auch die Idee, mysql-Abfragen so zu vergraben, beunruhigt mich – ich denke, es ist besser, Core-Methoden zu verwenden, um eine Lösung zu erreichen, um Konflikte mit zukünftigen WP-Updates zu vermeiden. Hier ist meine Lösung, die auf einem Kommentar Nr. 7 auf dem Trac-Ticket basiert, auf das er Bezug nimmt

 function get_terms_by_custom_post_type( $post_type, $taxonomy ){ $args = array( 'post_type' => $post_type); $loop = new WP_Query( $args ); $postids = array(); // build an array of post IDs while ( $loop->have_posts() ) : $loop->the_post(); array_push($postids, get_the_ID()); endwhile; // get taxonomy values based on array of IDs $regions = wp_get_object_terms( $postids, $taxonomy ); return $regions; } 

Verwendung:

 $terms = get_terms_by_custom_post_type('country','flag'); 

Dies funktioniert nur für einen Post-Typ und eine Taxonomie, denn das ist, was ich brauchte, aber es wäre nicht zu schwer, dies zu ändern, um mehrere Werte zu akzeptieren.

Es gab eine Erwähnung in diesem Trac-Thread, dass dies nicht gut skalieren kann, aber ich arbeite in einem ziemlich kleinen Maßstab und hatte keine Probleme mit der Geschwindigkeit.

[Bearbeiten] Dies ist ein Kommentar zu der ausgezeichneten Antwort von Stephen Harris.

Es gibt keine Begriffe zurück, wenn es mit mehreren Post-Typen wie diesem verwendet wird. $flags = wpse57444_get_terms('flags', array('post_types' => array('country','city'))); . Dies liegt daran, dass $ wpdb-> prepare die Zeichenfolge $ post_types_str auf p.post_type IN('country,city') p.post_type IN('country','city') während es p.post_type IN('country','city') . Sehen Sie dieses Ticket: 11102 . Verwenden Sie die Lösung aus diesem Thema, um dies zu umgehen : https://stackoverflow.com/a/10634225

Ich habe auch versucht, die Antwort von @stephen Harris zu verwenden, aber die Abfrage, die ich brauchte, war ziemlich schwierig, als eine einzige Abfrage zu schreiben und die Filterstücke zu verwenden.

Außerdem musste ich diese function mehrmals auf der gleichen Seite verwenden und triggerse das Problem, indem wpse_filter_terms_by_cpt function wpse_filter_terms_by_cpt außerhalb der Wrapper-function deklarierte.

Anyways @Mark Die Antwort von Pruce passt meiner Meinung nach besser, aus den gleichen Gründen, die er sagte, obwohl Sie eine weitere Abfrage (und die zugehörige Schleife) wp_get_object_terms , um die Argumente für die function wp_get_object_terms vorzubereiten.

Zwei benutzerdefinierte Beitragstypen “Land” und “Stadt” und eine gemeinsame Taxonomie “Flagge”. Sie möchten die Liste auf den Nachrichtentyp ‘Land’ beschränken.

Hier ist eine einfachere Lösung:

 $posts_in_post_type = get_posts( array( 'fields' => 'ids', 'post_type' => 'country', 'posts_per_page' => -1, ) ); $terms = wp_get_object_terms( $posts_in_post_type, 'flag', array( 'ids' ) ); ?> 

Verwende das hier

 $ args = array ('post_type' => 'land', 'nummer' => '999');
 $ terms = get_terms ('flag', $ args);
 foreach ($ terms als $ term) {echo ''.  $ term-> name.  '';  } 

Dies holt alle Thermen von Flags Taxonomie gehört zu Land CPT.