I have a custom post type "vendor" - and I want to people to drill down via custom taxonomies to see posts. I have two custom taxonomies - one for "service" and one for "location".

So in a custom template I am listing all the available services... when one is clicked I load in another display that lists all locations (and I pass along the service ID in the URL query string)... when a location is clicked... (I pass the service ID and Location ID again in the query string) and I load in a list of vendors that are categorized with both that service AND location.

The problem I'm running into is that there is the possibility that on that location list - it will include a location for which no posts have the previously selected service.

So basically - when I get that list of locations, I need a list of locations that have posts that ALSO have been categorized with a particular service so I don't end up with an empty list.

For example: let's say I select the service "photography" - and then from my list of locations I select "Boston" - but I don't have any photographers in Boston... since that's the case... I don't want "Boston" showing up in that list.

While my list of services is a simple "get_terms" call... I think I need a custom select query ($wpdb->get_results) to grab that list of locations, but I'm just not sure what the query needs to be...

1 Answer 1


I contacted Scribu because his Query Multiple Taxonomies plugin did what I was looking to do and he pointed me in the right direction. I've got this working (in my dev environment) so I think this is it. (Scribu had these split into two functions as part of a class - I'm sure that's the "classy" (pun unintended) way to do it - but this works inline: (Posting here in case it helps anyone else...)

//building this as if we were going to look for
//posts that have been categorized with this service
$tempargs = array('post_type' => 'vendors',
        'tax_query' => array(array(
                    'taxonomy' => 'service',
                    'field' => 'id',
                    'terms' => intval($_GET['srv'])
$args = array_merge( $tempargs, array(
        'fields' => 'ids',
        'nopaging' => true,
        'no_found_rows' => true,
        'ignore_sticky_post' => true,
        'cache_results' => false,
) );
$query = new WP_Query;
$filtered_ids = $query->query( $args );
//now getting the list of location terms that have posts in this service
$locationsWdups = wp_get_object_terms( $filtered_ids, 'location' ); 
//the above will include duplicate locations so we'll combine them
//into one array below
$locations = array();
foreach ( $locationsWdups as $singloc )
     $locations[ $singloc->term_id ] = $singloc;    

Then you can do a foreach on $locations...

(Please correct me if I've missed something or am doing something incorrectly)

  • Just one note - the $_GET['srv'] - I put the ID number of the service into the query string of the URL/page... so assuming the term ID for the service is 10 - the url looks like this: domain.com/page/?srv=10 Commented Aug 25, 2011 at 16:06
  • Thank you for posting this. It helped me with a similar situation. However, for me I received no duplicates, so I don't think I need the part at the end where you combine into one array. Perhaps the wp_get_object_terms has been updated over the years, or maybe my scenario was just different than yours in that it was unneccessary. One thing you may want to include in your query args is post_status => publish, so you don't get any drafts in the list. Also, I found I was able to combine the $tempargs and $args into one array with no issue. Commented May 11, 2018 at 0:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.