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

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'

  • Sadly, this didn't work =( unless of course I put it in the wrong place. Sorry, i'm a real newbie at this. I basically replaced my line under: //l List Categories wp_lsit_categories($args); With // List categories $args['echo'] = FALSE; return wp_list_categories($args); And i received the same result. Jun 30, 2020 at 11:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.