I’m trying to create a shortcode that can display a list of categories. However, it should:

  • First, limit the results to a specific post type (based on shortcode usage)
  • then check to see if category has any posts, if it doesn’t, omit it from the list
  • Finally, display list in alphabetical order

I found some code online that seems to work, if I want to use it as a page template, but I would like to use it as a shortcode so I can place it in a widget on my site.

For example, I would like to type: [catlist post_type=places] and it will display a list of categories under the post type “Places”.

Here is the code that is sort of working, however it places the list outside of the widget, almost in a div before the widget box.

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);

}
add_shortcode('catlist', 'wp_list_categories_for_post_type');

Thank you for anyone that can help.

1 Answer
1

It looks like wp_list_categories($args) will output directly when you call it, which is why the output comes out in a weird place. and ideally what you need is to capture the output and return it, but luckily wp_list_categories allows you to do this with the ‘echo’ parameter. Try:

$args['echo'] = FALSE;
return wp_list_categories($args);

Note the extra ‘return’

Leave a Reply

Your email address will not be published. Required fields are marked *