WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a custom taxonomy called 'locations' which is being shared across a bunch of post types. I want to make a select field dropdown list of my locations (terms) to let users go to the taxonomy term page for each specific location; however I want to exclude some terms which are used in one post type and perhaps not in the others.

Is there a way to accomplish this?

share|improve this question
up vote 1 down vote accepted

I'm not a programmer so there's probably a far more efficient/correct way of doing this.

Put this in functions.php or a custom plugin:

function get_terms_by_post_type( $taxonomies, $post_types ) {
    global $wpdb;
    $query = $wpdb->get_results( "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('".join( "', '", $post_types )."') AND tt.taxonomy IN('".join( "', '", $taxonomies )."') GROUP BY t.term_id");
    return $query;

function show_post_type_terms($taxonomy, $posttype = null ) {
   global $post;
   if(!isset($posttype)) $posttype = get_post_type( $post->ID );
   $terms = get_terms_by_post_type( array($taxonomy), array($posttype) );
   echo '<ul>';
   foreach($terms as $term) {
      $output = '<li><a href="'.get_bloginfo('url').'/'.$taxonomy.'/'.$term->slug.'/?post_type='.$posttype.'">'.$term->name.'</a></li>';
      echo $output;
   echo '</ul>';

Usage examples:

  1. Put <?php show_post_type_terms('taxonomy_name'); ?> into custom post type archive template file to show a list of terms of taxonomy_name, excluding all terms that are not used by post of the current custom post type, and linking to a term archive which shows only post of that specific post type.
  2. Put <?php show_post_type_terms('taxonomy_name', 'custom_post_type_name'); ?> in any other template file to do the same for a specific custom post type.
  3. You could also adapt it to act as a shortcode that you can place directly into a post or page, with something like [show_post_type_terms taxonomy="taxonomy_name" posttype="post_type_name"]. Let me know if you're looking for the code for this.

Adapted from this. ($wpdb->prepare was changed to $wpdb->get_results because of this)

share|improve this answer
$wpdb->prepare and $wpdb->get_results are completely different methods serving very different purposes. The one should not be converted to the other. The problem lies with the incorrect use of $wpdb->prepare in the code you reference. Please edit this answer so that it can stand on its own. As is, it takes two additional page views to be intelligible. – s_ha_dum Sep 17 '13 at 20:29
OK I amended it. As mentioned I'm not a programmer so feel free to improve it. I've the shortcode version running on my site and it's giving me the desired functionality. – user34682 Sep 18 '13 at 1:02

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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