Quite specific this but it was hard to work out, with ChatGPT and GitHub CoPilot failing to come up with a solution.

We have a custom_post type ‘case_study‘, and a taxonomy, ‘category‘ (which is also used by other post types) and we wanted to display a dropdown list of the taxonomy items only if there was at least one post of post_type ‘case_study‘ that used it. Essentially, hide non-used items.

This isn’t so difficult for normal posts, but for custom post types it gets complicated.

Let’s get to it, first we make an array of the taxonomy item IDs that have zero custom posts using it:

    // exclude categories without any case_study type posts
    $terms = get_terms( array(
        'taxonomy' => 'category',
        'hide_empty' => false,
    ) );
    foreach ( $terms as $term ) {
        $args = array(
            'post_type' => 'case_study',
            'tax_query' => array(
                    'taxonomy' => 'category',
                    'field' => 'slug',
                    'terms' => $term->slug,
            'posts_per_page' => -1,
            'fields' => 'ids',
        $query = new WP_Query( $args );
        $count = $query->post_count;
        if ( $count === 0 ) {
            $cat_excludes[] = $term->term_id;

This gives is an array $cat_excludes of term IDs that we want to exclude, which is useful as we can use wp_dropdown_categories to generate our dropdown list using its ‘exclude‘ param, like this:

                   wp_dropdown_categories( array(
                        'show_option_all'    => 'Topic',
                        'orderby'            => 'name', 
                        'order'              => 'ASC',
                        'show_count'         => 0,
                        'hide_empty'         => 0, 
                        'child_of'           => 0,
                        'exclude'            => $cat_excludes,   
                        'echo'               => 1,
                        'selected'           => $our_selected_id,
                        'hierarchical'       => true, 
                        'name'               => 'topics',
                        'id'                 => 'topics',
                        'class'              => 'postform post-filters',
                        'depth'              => 0,
                        'tab_index'          => 0,
                        'taxonomy'           => 'category',
                        'hide_if_empty'      => false,
                        'value_field'	     => 'term_id',
                    ) ); 

The name and id should match whatever you want to use in the form fields of course.

Now from a list of 50+ items we only see the ones with posts:

I’d love a better solution as I think this is a little heavy and should be cached rather than run on every page load.

Last modified: September 22, 2023



Write a Reply or Comment

Your email address will not be published.