I wrote a function that allows you to pass `post_type` in the `$args` array to the `get_terms()` function. It also checks whether `post_type` was passed via `$_GET` (this prevents taxonomies that are shared between CPTs but aren't assigned to the current custom post type from being displayed... lame partial workaround for http://wordpress.stackexchange.com/questions/17335/post-count-is-wrong-when-using-same-taxonomy-for-2-different-cpt). HT to @braydon for writing the SQL. /** * 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; $post_type = $args['post_type'] ? $args['post_type'] : $_GET['post_type'] && is_admin() ? $_GET['post_type'] : false; if ($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='$post_type'"; } return $clauses; } add_filter('terms_clauses', 'terms_clauses', 10, 3);