Only list categories that contain posts of a specific custom post type

I have three custom post types set up, articles, videos and photos.
I am using standard categories for these post types, and sharing the categories across all post types.

I am trying to create a nav menu for each post type, listing the categories, that should follow the following structure:

  • Photos

    • Cat 1
    • Cat 3
    • Cat 5
  • Videos

    • Cat 2
    • Cat 3
    • Cat 5
  • Articles

    • Cat 1
    • Cat 2
    • Cat 4

Categories that do not contain the custom post type should be hidden.

get_categories() with hide_empty set to 1 is obviously close, but it doesn’t allow you to specify a post type.

3 Answers
3

Put the following in your functions.php:

function wp_list_categories_for_post_type($post_type, $args="") {
    $exclude = array();

    // Check ALL categories for posts of given post type
    foreach (get_categories() as $category) {
        $posts = get_posts(array('post_type' => $post_type, 'category' => $category->cat_ID));

        // If no posts found, ...
        if (empty($posts))
            // ...add category to exclude list
            $exclude[] = $category->cat_ID;
    }

    // Set up args
    if (! empty($exclude)) {
        $args .= ('' === $args) ? '' : '&';
        $args .= 'exclude=".implode(",', $exclude);
    }

    // List categories
    wp_list_categories($args);
}

Now you can call wp_list_categories_for_post_type('photos'); or wp_list_categories_for_post_type('videos', 'order=DESC&title_li=Cats'); and the like.

Leave a Comment