In WordPress, to get terms using get_terms()
and filter them by post type (post_type
), you need to perform an additional SQL query since get_terms()
does not provide direct options for filtering by post type.
You can either use meta_query
or work through relationships with posts. Here’s a step-by-step method:
Example of getting terms that have posts of a specific post_type
- Step 1: Get the post IDs of the specific post type First, get the IDs of the posts related to the specific type.
- Step 2: Get terms associated with these posts After retrieving the post IDs, you can filter the terms.
Here’s an example code:
function get_terms_with_post_type($taxonomy, $post_type) {
global $wpdb;
// Query to get terms associated with posts of a specific type
$query = $wpdb->prepare("
SELECT t.term_id
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 tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
INNER JOIN {$wpdb->posts} AS p ON p.ID = tr.object_id
WHERE tt.taxonomy = %s
AND p.post_type = %s
AND p.post_status = 'publish'
GROUP BY t.term_id
", $taxonomy, $post_type);
// Get term IDs
$term_ids = $wpdb->get_col($query);
// Get term objects
if (!empty($term_ids)) {
return get_terms([
'taxonomy' => $taxonomy,
'include' => $term_ids,
]);
}
return [];
}
// Usage
$terms = get_terms_with_post_type('category', 'custom_post_type');
foreach ($terms as $term) {
echo $term->name . '<br>';
}
Explanation of the code:
$wpdb->prepare
: Used to safely execute SQL queries with parameters.- SQL Query:
- Joins the
terms
,term_taxonomy
,term_relationships
, andposts
tables. - Filters posts by status (
publish
) andpost_type
. - Groups the results by term IDs to avoid duplicates.
- Joins the
get_terms()
: Retrieves terms by the list of IDs found in the SQL query.
Alternative method: WP_Query + get_terms
If SQL queries are undesirable, you can use WP_Query
to filter posts by post_type
and then get terms from the posts. This method is less efficient:
function get_terms_with_wp_query($taxonomy, $post_type) {
$query = new WP_Query([
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids', // Return only post IDs
]);
if ($query->have_posts()) {
$post_ids = $query->posts;
return wp_get_object_terms($post_ids, $taxonomy);
}
return [];
}
// Usage
$terms = get_terms_with_wp_query('category', 'custom_post_type');
foreach ($terms as $term) {
echo $term->name . '<br>';
}
This method does not require direct SQL queries, but it may be slower if you have many posts.
Both approaches will give you the terms related to posts of a specific type.