Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Filter Taxonomy List by Another Taxonomy Term WordPress


I have two taxonomies, that cover multiple post types. I want to get a tag cloud (a list actually is fine) of all terms from a particular taxonomy, that have a specific term in another taxonomy.

So like this: show all genre terms that have at least one associated post, where those associated posts also have the term Russell Crowe (or his ID) in the Actor taxonomy.

(Genre is obviously be another taxonomy.)


Answers (1)


John Cotton answers:

This might work:

// Start with whatever ID you want to have from Actor
$r_crowe = 17;

// Get all those post_ids for that term
$post_ids = get_objects_in_term( $r_crowe, 'actor' );

// The get then the genre terms for those post ids
$terms = wp_get_object_terms( $post_ids, 'genre', array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all') );

weaver comments:

That would work but I need the terms to be distinct. Your solution would provide the Action genre multiple times (assuming Crowe was in multiple "action" posts.) :)

I'd also have a concern about performance--does perform only two sql queries, or one for each post_id?

We're close!

John Cotton comments:

If you want a unique list of terms then change the last line to:

$terms = array_values( array_unique( wp_get_object_terms( $post_ids, 'genre', array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all') ) ) );

I take your point on the performance, I often feel the same. But with WordPress it's a balance between raw SQL and platform code that you will carry on working...

I use wp_get_object_terms in several ajax routines on sites and have always found performance to be acceptable.

John Cotton comments:

Each of those functions only makes one SQL call.

weaver comments:

You won it.

But to clarify, fields=>all returns objects which array_unique won't compare (at least doesn't seem to.) Any thoughts there? I know I can use fields=>names, that works, but it'd be great to keep the All attribute as I kind of need the ID as well as the name.

(I know I can do a test loop, but natively or would be better.)

John Cotton comments:

You're absolutely right - that args array should have read:

array( 'fields' => 'ids' )

(assuming order isn't important).

John Cotton comments:

If you need the name, you could use the id in a loop to call get_term to do whatever output you want for each term.

That would mean multiple calls to the database (one for each term) but caching would help that and - providing it's only a relatively short list - then those extra round trips shouldn't be too significant in an overall WP page.

If you are worried about performance then take a look at WP_Object_Cache and considered how you might cache results for popular actors.

weaver comments:

Great John, thanks tons!