wp_list_categories

The timeline below displays how wordpress function wp_list_categories has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.4

/**
 * Displays or retrieves the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments.
 * @since 4.4.0 The `current_category` argument was modified to optionally accept an array of values.
 * @since 6.1.0 Default value of the 'use_desc_for_title' argument was changed from 1 to 0.
 *
 * @param array|string $args {
 *     Array of optional arguments. See get_categories(), get_terms(), and WP_Term_Query::__construct()
 *     for information on additional accepted arguments.
 *
 *     @type int|int[]    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1, or their
 *                                               bool equivalents. Default 1.
 *     @type int[]|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type int[]|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to include post counts. Accepts 0, 1, or their bool equivalents.
 *                                               Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $taxonomy              Name of the taxonomy to retrieve. Default 'category'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Accepts 0, 1, or their bool equivalents. Default 0.
 *     @type Walker       $walker                Walker object to use to build the output. Default empty which results
 *                                               in a Walker_Category instance being used.
 * }
 * @return void|string|false Void if 'echo' argument is true, HTML list of categories if 'echo' is false.
 *                           False if the taxonomy does not exist.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 0);
    $parsed_args = wp_parse_args($args, $defaults);
    if (!isset($parsed_args['pad_counts']) && $parsed_args['show_count'] && $parsed_args['hierarchical']) {
        $parsed_args['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if ($parsed_args['hierarchical']) {
        $exclude_tree = array();
        if ($parsed_args['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude_tree']));
        }
        if ($parsed_args['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude']));
        }
        $parsed_args['exclude_tree'] = $exclude_tree;
        $parsed_args['exclude'] = '';
    }
    if (!isset($parsed_args['class'])) {
        $parsed_args['class'] = ('category' === $parsed_args['taxonomy']) ? 'categories' : $parsed_args['taxonomy'];
    }
    if (!taxonomy_exists($parsed_args['taxonomy'])) {
        return false;
    }
    $show_option_all = $parsed_args['show_option_all'];
    $show_option_none = $parsed_args['show_option_none'];
    $categories = get_categories($parsed_args);
    $output = '';
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($parsed_args['class']) . '">' . $parsed_args['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' === $parsed_args['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($parsed_args['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type, true) && !in_array('page', $taxonomy_object->object_type, true)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' === get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' === $parsed_args['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($parsed_args['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy) {
                $parsed_args['current_category'] = get_queried_object_id();
            }
        }
        if ($parsed_args['hierarchical']) {
            $depth = $parsed_args['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $parsed_args);
    }
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string       $output HTML output.
     * @param array|string $args   An array or query string of taxonomy-listing arguments. See
     *                             wp_list_categories() for information on accepted arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($parsed_args['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 6.1

/**
 * Displays or retrieves the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments.
 * @since 4.4.0 The `current_category` argument was modified to optionally accept an array of values.
 * @since 6.1.0 Default value of the 'use_desc_for_title' argument was changed from 1 to 0.
 *
 * @param array|string $args {
 *     Array of optional arguments. See get_categories(), get_terms(), and WP_Term_Query::__construct()
 *     for information on additional accepted arguments.
 *
 *     @type int|int[]    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1, or their
 *                                               bool equivalents. Default 1.
 *     @type int[]|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type int[]|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to include post counts. Accepts 0, 1, or their bool equivalents.
 *                                               Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $taxonomy              Name of the taxonomy to retrieve. Default 'category'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Accepts 0, 1, or their bool equivalents. Default 0.
 *     @type Walker       $walker                Walker object to use to build the output. Default empty which results
 *                                               in a Walker_Category instance being used.
 * }
 * @return void|string|false Void if 'echo' argument is true, HTML list of categories if 'echo' is false.
 *                           False if the taxonomy does not exist.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 0);
    $parsed_args = wp_parse_args($args, $defaults);
    if (!isset($parsed_args['pad_counts']) && $parsed_args['show_count'] && $parsed_args['hierarchical']) {
        $parsed_args['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $parsed_args['hierarchical']) {
        $exclude_tree = array();
        if ($parsed_args['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude_tree']));
        }
        if ($parsed_args['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude']));
        }
        $parsed_args['exclude_tree'] = $exclude_tree;
        $parsed_args['exclude'] = '';
    }
    if (!isset($parsed_args['class'])) {
        $parsed_args['class'] = ('category' === $parsed_args['taxonomy']) ? 'categories' : $parsed_args['taxonomy'];
    }
    if (!taxonomy_exists($parsed_args['taxonomy'])) {
        return false;
    }
    $show_option_all = $parsed_args['show_option_all'];
    $show_option_none = $parsed_args['show_option_none'];
    $categories = get_categories($parsed_args);
    $output = '';
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($parsed_args['class']) . '">' . $parsed_args['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' === $parsed_args['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($parsed_args['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type, true) && !in_array('page', $taxonomy_object->object_type, true)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' === get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' === $parsed_args['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($parsed_args['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy) {
                $parsed_args['current_category'] = get_queried_object_id();
            }
        }
        if ($parsed_args['hierarchical']) {
            $depth = $parsed_args['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $parsed_args);
    }
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string       $output HTML output.
     * @param array|string $args   An array or query string of taxonomy-listing arguments. See
     *                             wp_list_categories() for information on accepted arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($parsed_args['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 5.9

/**
 * Displays or retrieves the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments.
 * @since 4.4.0 The `current_category` argument was modified to optionally accept an array of values.
 *
 * @param array|string $args {
 *     Array of optional arguments. See get_categories(), get_terms(), and WP_Term_Query::__construct()
 *     for information on additional accepted arguments.
 *
 *     @type int|int[]    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1, or their
 *                                               bool equivalents. Default 1.
 *     @type int[]|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type int[]|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to include post counts. Accepts 0, 1, or their bool equivalents.
 *                                               Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $taxonomy              Name of the taxonomy to retrieve. Default 'category'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Accepts 0, 1, or their bool equivalents. Default 1.
 * }
 * @return void|string|false Void if 'echo' argument is true, HTML list of categories if 'echo' is false.
 *                           False if the taxonomy does not exist.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $parsed_args = wp_parse_args($args, $defaults);
    if (!isset($parsed_args['pad_counts']) && $parsed_args['show_count'] && $parsed_args['hierarchical']) {
        $parsed_args['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $parsed_args['hierarchical']) {
        $exclude_tree = array();
        if ($parsed_args['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude_tree']));
        }
        if ($parsed_args['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude']));
        }
        $parsed_args['exclude_tree'] = $exclude_tree;
        $parsed_args['exclude'] = '';
    }
    if (!isset($parsed_args['class'])) {
        $parsed_args['class'] = ('category' === $parsed_args['taxonomy']) ? 'categories' : $parsed_args['taxonomy'];
    }
    if (!taxonomy_exists($parsed_args['taxonomy'])) {
        return false;
    }
    $show_option_all = $parsed_args['show_option_all'];
    $show_option_none = $parsed_args['show_option_none'];
    $categories = get_categories($parsed_args);
    $output = '';
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($parsed_args['class']) . '">' . $parsed_args['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' === $parsed_args['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($parsed_args['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type, true) && !in_array('page', $taxonomy_object->object_type, true)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' === get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' === $parsed_args['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($parsed_args['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy) {
                $parsed_args['current_category'] = get_queried_object_id();
            }
        }
        if ($parsed_args['hierarchical']) {
            $depth = $parsed_args['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $parsed_args);
    }
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string       $output HTML output.
     * @param array|string $args   An array or query string of taxonomy-listing arguments. See
     *                             wp_list_categories() for information on accepted arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($parsed_args['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 5.7

/**
 * Displays or retrieves the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments.
 * @since 4.4.0 The `current_category` argument was modified to optionally accept an array of values.
 *
 * @param array|string $args {
 *     Array of optional arguments. See get_categories(), get_terms(), and WP_Term_Query::__construct()
 *     for information on additional accepted arguments.
 *
 *     @type int|int[]    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1, or their
 *                                               bool equivalents. Default 1.
 *     @type int[]|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type int[]|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to include post counts. Accepts 0, 1, or their bool equivalents.
 *                                               Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $taxonomy              Name of the taxonomy to retrieve. Default 'category'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Accepts 0, 1, or their bool equivalents. Default 1.
 * }
 * @return void|string|false Void if 'echo' argument is true, HTML list of categories if 'echo' is false.
 *                           False if the taxonomy does not exist.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $parsed_args = wp_parse_args($args, $defaults);
    if (!isset($parsed_args['pad_counts']) && $parsed_args['show_count'] && $parsed_args['hierarchical']) {
        $parsed_args['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $parsed_args['hierarchical']) {
        $exclude_tree = array();
        if ($parsed_args['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude_tree']));
        }
        if ($parsed_args['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude']));
        }
        $parsed_args['exclude_tree'] = $exclude_tree;
        $parsed_args['exclude'] = '';
    }
    if (!isset($parsed_args['class'])) {
        $parsed_args['class'] = ('category' === $parsed_args['taxonomy']) ? 'categories' : $parsed_args['taxonomy'];
    }
    if (!taxonomy_exists($parsed_args['taxonomy'])) {
        return false;
    }
    $show_option_all = $parsed_args['show_option_all'];
    $show_option_none = $parsed_args['show_option_none'];
    $categories = get_categories($parsed_args);
    $output = '';
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($parsed_args['class']) . '">' . $parsed_args['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' === $parsed_args['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($parsed_args['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type, true) && !in_array('page', $taxonomy_object->object_type, true)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' === get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' === $parsed_args['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($parsed_args['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy) {
                $parsed_args['current_category'] = get_queried_object_id();
            }
        }
        if ($parsed_args['hierarchical']) {
            $depth = $parsed_args['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $parsed_args);
    }
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments. See wp_list_categories()
     *                       for information on accepted arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($parsed_args['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 5.6

/**
 * Displays or retrieves the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments.
 * @since 4.4.0 The `current_category` argument was modified to optionally accept an array of values.
 *
 * @param array|string $args {
 *     Array of optional arguments. See get_categories(), get_terms(), and WP_Term_Query::__construct()
 *     for information on additional accepted arguments.
 *
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1, or their
 *                                               bool equivalents. Default 1.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to include post counts. Accepts 0, 1, or their bool equivalents.
 *                                               Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $taxonomy              Name of the taxonomy to retrieve. Default 'category'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Accepts 0, 1, or their bool equivalents. Default 1.
 * }
 * @return void|string|false Void if 'echo' argument is true, HTML list of categories if 'echo' is false.
 *                           False if the taxonomy does not exist.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $parsed_args = wp_parse_args($args, $defaults);
    if (!isset($parsed_args['pad_counts']) && $parsed_args['show_count'] && $parsed_args['hierarchical']) {
        $parsed_args['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $parsed_args['hierarchical']) {
        $exclude_tree = array();
        if ($parsed_args['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude_tree']));
        }
        if ($parsed_args['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude']));
        }
        $parsed_args['exclude_tree'] = $exclude_tree;
        $parsed_args['exclude'] = '';
    }
    if (!isset($parsed_args['class'])) {
        $parsed_args['class'] = ('category' === $parsed_args['taxonomy']) ? 'categories' : $parsed_args['taxonomy'];
    }
    if (!taxonomy_exists($parsed_args['taxonomy'])) {
        return false;
    }
    $show_option_all = $parsed_args['show_option_all'];
    $show_option_none = $parsed_args['show_option_none'];
    $categories = get_categories($parsed_args);
    $output = '';
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($parsed_args['class']) . '">' . $parsed_args['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' === $parsed_args['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($parsed_args['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type, true) && !in_array('page', $taxonomy_object->object_type, true)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' === get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' === $parsed_args['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($parsed_args['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy) {
                $parsed_args['current_category'] = get_queried_object_id();
            }
        }
        if ($parsed_args['hierarchical']) {
            $depth = $parsed_args['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $parsed_args);
    }
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($parsed_args['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 5.5

/**
 * Displays or retrieves the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments.
 * @since 4.4.0 The `current_category` argument was modified to optionally accept an array of values.
 *
 * @param array|string $args {
 *     Array of optional arguments. See get_categories(), get_terms(), and WP_Term_Query::__construct()
 *     for information on additional accepted arguments.
 *
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1, or their
 *                                               bool equivalents. Default 1.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to include post counts. Accepts 0, 1, or their bool equivalents.
 *                                               Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Accepts 0, 1, or their bool equivalents. Default 1.
 * }
 * @return void|string|false Void if 'echo' argument is true, HTML list of categories if 'echo' is false.
 *                           False if the taxonomy does not exist.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $parsed_args = wp_parse_args($args, $defaults);
    if (!isset($parsed_args['pad_counts']) && $parsed_args['show_count'] && $parsed_args['hierarchical']) {
        $parsed_args['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $parsed_args['hierarchical']) {
        $exclude_tree = array();
        if ($parsed_args['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude_tree']));
        }
        if ($parsed_args['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude']));
        }
        $parsed_args['exclude_tree'] = $exclude_tree;
        $parsed_args['exclude'] = '';
    }
    if (!isset($parsed_args['class'])) {
        $parsed_args['class'] = ('category' === $parsed_args['taxonomy']) ? 'categories' : $parsed_args['taxonomy'];
    }
    if (!taxonomy_exists($parsed_args['taxonomy'])) {
        return false;
    }
    $show_option_all = $parsed_args['show_option_all'];
    $show_option_none = $parsed_args['show_option_none'];
    $categories = get_categories($parsed_args);
    $output = '';
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($parsed_args['class']) . '">' . $parsed_args['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' === $parsed_args['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($parsed_args['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type, true) && !in_array('page', $taxonomy_object->object_type, true)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' === get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' === $parsed_args['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($parsed_args['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy) {
                $parsed_args['current_category'] = get_queried_object_id();
            }
        }
        if ($parsed_args['hierarchical']) {
            $depth = $parsed_args['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $parsed_args);
    }
    if ($parsed_args['title_li'] && 'list' === $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($parsed_args['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 5.4

/**
 * Display or retrieve the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments.
 * @since 4.4.0 The `current_category` argument was modified to optionally accept an array of values.
 *
 * @param array|string $args {
 *     Array of optional arguments. See get_categories(), get_terms(), and WP_Term_Query::__construct()
 *     for information on additional accepted arguments.
 *
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1, or their
 *                                               bool equivalents. Default 1.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to include post counts. Accepts 0, 1, or their bool equivalents.
 *                                               Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Accepts 0, 1, or their bool equivalents. Default 1.
 * }
 * @return void|string|false Void if 'echo' argument is true, HTML list of categories if 'echo' is false.
 *                           False if the taxonomy does not exist.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $parsed_args = wp_parse_args($args, $defaults);
    if (!isset($parsed_args['pad_counts']) && $parsed_args['show_count'] && $parsed_args['hierarchical']) {
        $parsed_args['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $parsed_args['hierarchical']) {
        $exclude_tree = array();
        if ($parsed_args['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude_tree']));
        }
        if ($parsed_args['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude']));
        }
        $parsed_args['exclude_tree'] = $exclude_tree;
        $parsed_args['exclude'] = '';
    }
    if (!isset($parsed_args['class'])) {
        $parsed_args['class'] = ('category' == $parsed_args['taxonomy']) ? 'categories' : $parsed_args['taxonomy'];
    }
    if (!taxonomy_exists($parsed_args['taxonomy'])) {
        return false;
    }
    $show_option_all = $parsed_args['show_option_all'];
    $show_option_none = $parsed_args['show_option_none'];
    $categories = get_categories($parsed_args);
    $output = '';
    if ($parsed_args['title_li'] && 'list' == $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($parsed_args['class']) . '">' . $parsed_args['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $parsed_args['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($parsed_args['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type) && !in_array('page', $taxonomy_object->object_type)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' == get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' == $parsed_args['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($parsed_args['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy) {
                $parsed_args['current_category'] = get_queried_object_id();
            }
        }
        if ($parsed_args['hierarchical']) {
            $depth = $parsed_args['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $parsed_args);
    }
    if ($parsed_args['title_li'] && 'list' == $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($parsed_args['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 5.3

/**
 * Display or retrieve the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments.
 * @since 4.4.0 The `current_category` argument was modified to optionally accept an array of values.
 *
 * @param array|string $args {
 *     Array of optional arguments. See get_categories(), get_terms(), and WP_Term_Query::__construct()
 *     for information on additional accepted arguments.
 *
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  True to echo markup, false to return it. Default 1.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to show how many posts are in the category. Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Default 1.
 * }
 * @return false|string HTML list of categories only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $parsed_args = wp_parse_args($args, $defaults);
    if (!isset($parsed_args['pad_counts']) && $parsed_args['show_count'] && $parsed_args['hierarchical']) {
        $parsed_args['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $parsed_args['hierarchical']) {
        $exclude_tree = array();
        if ($parsed_args['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude_tree']));
        }
        if ($parsed_args['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($parsed_args['exclude']));
        }
        $parsed_args['exclude_tree'] = $exclude_tree;
        $parsed_args['exclude'] = '';
    }
    if (!isset($parsed_args['class'])) {
        $parsed_args['class'] = ('category' == $parsed_args['taxonomy']) ? 'categories' : $parsed_args['taxonomy'];
    }
    if (!taxonomy_exists($parsed_args['taxonomy'])) {
        return false;
    }
    $show_option_all = $parsed_args['show_option_all'];
    $show_option_none = $parsed_args['show_option_none'];
    $categories = get_categories($parsed_args);
    $output = '';
    if ($parsed_args['title_li'] && 'list' == $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($parsed_args['class']) . '">' . $parsed_args['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $parsed_args['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($parsed_args['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type) && !in_array('page', $taxonomy_object->object_type)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' == get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' == $parsed_args['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($parsed_args['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy) {
                $parsed_args['current_category'] = get_queried_object_id();
            }
        }
        if ($parsed_args['hierarchical']) {
            $depth = $parsed_args['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $parsed_args);
    }
    if ($parsed_args['title_li'] && 'list' == $parsed_args['style'] && (!empty($categories) || !$parsed_args['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($parsed_args['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 4.9

/**
 * Display or retrieve the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments. The `current_category` argument was modified to
 *              optionally accept an array of values.
 *
 * @param string|array $args {
 *     Array of optional arguments.
 *
 *     @type int          $child_of              Term ID to retrieve child terms of. See get_terms(). Default 0.
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  True to echo markup, false to return it. Default 1.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool|int     $hide_empty            Whether to hide categories that don't have any posts attached to them.
 *                                               Default 1.
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type bool         $hierarchical          Whether to include terms that have non-empty descendants.
 *                                               See get_terms(). Default true.
 *     @type string       $order                 Which direction to order categories. Accepts 'ASC' or 'DESC'.
 *                                               Default 'ASC'.
 *     @type string       $orderby               The column to use for ordering categories. Default 'name'.
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to show how many posts are in the category. Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $taxonomy              Taxonomy name. Default 'category'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Default 1.
 * }
 * @return false|string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $r['hierarchical']) {
        $exclude_tree = array();
        if ($r['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude_tree']));
        }
        if ($r['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude']));
        }
        $r['exclude_tree'] = $exclude_tree;
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    if (!taxonomy_exists($r['taxonomy'])) {
        return false;
    }
    $show_option_all = $r['show_option_all'];
    $show_option_none = $r['show_option_none'];
    $categories = get_categories($r);
    $output = '';
    if ($r['title_li'] && 'list' == $r['style'] && (!empty($categories) || !$r['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($r['class']) . '">' . $r['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $r['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($r['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type) && !in_array('page', $taxonomy_object->object_type)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' == get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' == $r['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($r['hierarchical']) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($r['title_li'] && 'list' == $r['style'] && (!empty($categories) || !$r['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($r['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 4.7

/**
 * Display or retrieve the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments. The `current_category` argument was modified to
 *              optionally accept an array of values.
 *
 * @param string|array $args {
 *     Array of optional arguments.
 *
 *     @type int          $child_of              Term ID to retrieve child terms of. See get_terms(). Default 0.
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  True to echo markup, false to return it. Default 1.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool|int     $hide_empty            Whether to hide categories that don't have any posts attached to them.
 *                                               Default 1.
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type bool         $hierarchical          Whether to include terms that have non-empty descendants.
 *                                               See get_terms(). Default true.
 *     @type string       $order                 Which direction to order categories. Accepts 'ASC' or 'DESC'.
 *                                               Default 'ASC'.
 *     @type string       $orderby               The column to use for ordering categories. Default 'ID'.
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to show how many posts are in the category. Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $taxonomy              Taxonomy name. Default 'category'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Default 1.
 * }
 * @return false|string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $r['hierarchical']) {
        $exclude_tree = array();
        if ($r['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude_tree']));
        }
        if ($r['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude']));
        }
        $r['exclude_tree'] = $exclude_tree;
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    if (!taxonomy_exists($r['taxonomy'])) {
        return false;
    }
    $show_option_all = $r['show_option_all'];
    $show_option_none = $r['show_option_none'];
    $categories = get_categories($r);
    $output = '';
    if ($r['title_li'] && 'list' == $r['style'] && (!empty($categories) || !$r['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($r['class']) . '">' . $r['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $r['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($r['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type) && !in_array('page', $taxonomy_object->object_type)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' == get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' == $r['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($r['hierarchical']) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($r['title_li'] && 'list' == $r['style'] && (!empty($categories) || !$r['hide_title_if_empty'])) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($r['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 4.6

/**
 * Display or retrieve the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments. The `current_category` argument was modified to
 *              optionally accept an array of values.
 *
 * @param string|array $args {
 *     Array of optional arguments.
 *
 *     @type int          $child_of              Term ID to retrieve child terms of. See get_terms(). Default 0.
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type bool|int     $echo                  True to echo markup, false to return it. Default 1.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See get_terms().
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See get_terms(). Default empty string.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type string       $feed_type             Feed type. Used to build feed link. See get_term_feed_link().
 *                                               Default empty string (default feed).
 *     @type bool|int     $hide_empty            Whether to hide categories that don't have any posts attached to them.
 *                                               Default 1.
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type bool         $hierarchical          Whether to include terms that have non-empty descendants.
 *                                               See get_terms(). Default true.
 *     @type string       $order                 Which direction to order categories. Accepts 'ASC' or 'DESC'.
 *                                               Default 'ASC'.
 *     @type string       $orderby               The column to use for ordering categories. Default 'ID'.
 *     @type string       $separator             Separator between links. Default '<br />'.
 *     @type bool|int     $show_count            Whether to show how many posts are in the category. Default 0.
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $style                 The style used to display the categories list. If 'list', categories
 *                                               will be output as an unordered list. If left empty or another value,
 *                                               categories will be output separated by `<br>` tags. Default 'list'.
 *     @type string       $taxonomy              Taxonomy name. Default 'category'.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Default 1.
 * }
 * @return false|string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $r['hierarchical']) {
        $exclude_tree = array();
        if ($r['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude_tree']));
        }
        if ($r['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude']));
        }
        $r['exclude_tree'] = $exclude_tree;
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    if (!taxonomy_exists($r['taxonomy'])) {
        return false;
    }
    $show_option_all = $r['show_option_all'];
    $show_option_none = $r['show_option_none'];
    $categories = get_categories($r);
    $output = '';
    if ($r['title_li'] && 'list' == $r['style'] && (!empty($categories) || !$r['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($r['class']) . '">' . $r['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $r['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($r['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type) && !in_array('page', $taxonomy_object->object_type)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' == get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' == $r['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($r['hierarchical']) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($r['title_li'] && 'list' == $r['style']) {
        $output .= '</ul></li>';
    }
    /**
     * Filters the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($r['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 4.5

/**
 * Display or retrieve the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments. The `current_category` argument was modified to
 *              optionally accept an array of values.
 *
 * @param string|array $args {
 *     Array of optional arguments.
 *
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $orderby               The column to use for ordering categories. Default 'ID'.
 *     @type string       $order                 Which direction to order categories. Accepts 'ASC' or 'DESC'.
 *                                               Default 'ASC'.
 *     @type bool|int     $show_count            Whether to show how many posts are in the category. Default 0.
 *     @type bool|int     $hide_empty            Whether to hide categories that don't have any posts attached to them.
 *                                               Default 1.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Default 1.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_type             Feed type. Used to build feed link. See {@link get_term_feed_link()}.
 *                                               Default empty string (default feed).
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type int          $child_of              Term ID to retrieve child terms of. See {@link get_terms()}. Default 0.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See {@link get_terms()}.
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See {@link get_terms()}. Default empty string.
 *     @type bool|int     $echo                  True to echo markup, false to return it. Default 1.
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type bool         $hierarchical          Whether to include terms that have non-empty descendants.
 *                                               See {@link get_terms()}. Default true.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type string       $taxonomy              Taxonomy name. Default 'category'.
 *     @type string       $separator             Separator between links. Default '<br />'.
 * }
 * @return false|string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __('No categories'), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __('Categories'), 'use_desc_for_title' => 1);
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $r['hierarchical']) {
        $exclude_tree = array();
        if ($r['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude_tree']));
        }
        if ($r['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude']));
        }
        $r['exclude_tree'] = $exclude_tree;
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    if (!taxonomy_exists($r['taxonomy'])) {
        return false;
    }
    $show_option_all = $r['show_option_all'];
    $show_option_none = $r['show_option_none'];
    $categories = get_categories($r);
    $output = '';
    if ($r['title_li'] && 'list' == $r['style'] && (!empty($categories) || !$r['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($r['class']) . '">' . $r['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $r['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($r['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type) && !in_array('page', $taxonomy_object->object_type)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' == get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' == $r['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($r['hierarchical']) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($r['title_li'] && 'list' == $r['style']) {
        $output .= '</ul></li>';
    }
    /**
     * Filter the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($r['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 4.1

/**
 * Display or retrieve the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments. The `current_category` argument was modified to
 *              optionally accept an array of values.
 *
 * @param string|array $args {
 *     Array of optional arguments.
 *
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $orderby               The column to use for ordering categories. Default 'ID'.
 *     @type string       $order                 Which direction to order categories. Accepts 'ASC' or 'DESC'.
 *                                               Default 'ASC'.
 *     @type bool|int     $show_count            Whether to show how many posts are in the category. Default 0.
 *     @type bool|int     $hide_empty            Whether to hide categories that don't have any posts attached to them.
 *                                               Default 1.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Default 1.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_type             Feed type. Used to build feed link. See {@link get_term_feed_link()}.
 *                                               Default empty string (default feed).
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type int          $child_of              Term ID to retrieve child terms of. See {@link get_terms()}. Default 0.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See {@link get_terms()}.
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See {@link get_terms()}. Default empty string.
 *     @type bool|int     $echo                  True to echo markup, false to return it. Default 1.
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type bool         $hierarchical          Whether to include terms that have non-empty descendants.
 *                                               See {@link get_terms()}. Default true.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type string       $taxonomy              Taxonomy name. Default 'category'.
 * }
 * @return false|string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('show_option_all' => '', 'show_option_none' => __('No categories'), 'orderby' => 'name', 'order' => 'ASC', 'style' => 'list', 'show_count' => 0, 'hide_empty' => 1, 'use_desc_for_title' => 1, 'child_of' => 0, 'feed' => '', 'feed_type' => '', 'feed_image' => '', 'exclude' => '', 'exclude_tree' => '', 'current_category' => 0, 'hierarchical' => true, 'title_li' => __('Categories'), 'hide_title_if_empty' => false, 'echo' => 1, 'depth' => 0, 'separator' => '<br />', 'taxonomy' => 'category');
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $r['hierarchical']) {
        $exclude_tree = array();
        if ($r['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude_tree']));
        }
        if ($r['exclude']) {
            $exclude_tree = array_merge($exclude_tree, wp_parse_id_list($r['exclude']));
        }
        $r['exclude_tree'] = $exclude_tree;
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    if (!taxonomy_exists($r['taxonomy'])) {
        return false;
    }
    $show_option_all = $r['show_option_all'];
    $show_option_none = $r['show_option_none'];
    $categories = get_categories($r);
    $output = '';
    if ($r['title_li'] && 'list' == $r['style'] && (!empty($categories) || !$r['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($r['class']) . '">' . $r['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $r['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($r['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type) && !in_array('page', $taxonomy_object->object_type)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' == get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' == $r['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($r['hierarchical']) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($r['title_li'] && 'list' == $r['style']) {
        $output .= '</ul></li>';
    }
    /**
     * Filter the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($r['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 4.4

/**
 * Display or retrieve the HTML list of categories.
 *
 * @since 2.1.0
 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments. The `current_category` argument was modified to
 *              optionally accept an array of values.
 *
 * @param string|array $args {
 *     Array of optional arguments.
 *
 *     @type string       $show_option_all       Text to display for showing all categories. Default empty string.
 *     @type string       $show_option_none      Text to display for the 'no categories' option.
 *                                               Default 'No categories'.
 *     @type string       $orderby               The column to use for ordering categories. Default 'ID'.
 *     @type string       $order                 Which direction to order categories. Accepts 'ASC' or 'DESC'.
 *                                               Default 'ASC'.
 *     @type bool|int     $show_count            Whether to show how many posts are in the category. Default 0.
 *     @type bool|int     $hide_empty            Whether to hide categories that don't have any posts attached to them.
 *                                               Default 1.
 *     @type bool|int     $use_desc_for_title    Whether to use the category description as the title attribute.
 *                                               Default 1.
 *     @type string       $feed                  Text to use for the feed link. Default 'Feed for all posts filed
 *                                               under [cat name]'.
 *     @type string       $feed_type             Feed type. Used to build feed link. See {@link get_term_feed_link()}.
 *                                               Default empty string (default feed).
 *     @type string       $feed_image            URL of an image to use for the feed link. Default empty string.
 *     @type int          $child_of              Term ID to retrieve child terms of. See {@link get_terms()}. Default 0.
 *     @type array|string $exclude               Array or comma/space-separated string of term IDs to exclude.
 *                                               If `$hierarchical` is true, descendants of `$exclude` terms will also
 *                                               be excluded; see `$exclude_tree`. See {@link get_terms()}.
 *                                               Default empty string.
 *     @type array|string $exclude_tree          Array or comma/space-separated string of term IDs to exclude, along
 *                                               with their descendants. See {@link get_terms()}. Default empty string.
 *     @type bool|int     $echo                  True to echo markup, false to return it. Default 1.
 *     @type int|array    $current_category      ID of category, or array of IDs of categories, that should get the
 *                                               'current-cat' class. Default 0.
 *     @type bool         $hierarchical          Whether to include terms that have non-empty descendants.
 *                                               See {@link get_terms()}. Default true.
 *     @type string       $title_li              Text to use for the list title `<li>` element. Pass an empty string
 *                                               to disable. Default 'Categories'.
 *     @type bool         $hide_title_if_empty   Whether to hide the `$title_li` element if there are no terms in
 *                                               the list. Default false (title will always be shown).
 *     @type int          $depth                 Category depth. Used for tab indentation. Default 0.
 *     @type string       $taxonomy              Taxonomy name. Default 'category'.
 * }
 * @return false|string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('show_option_all' => '', 'show_option_none' => __('No categories'), 'orderby' => 'name', 'order' => 'ASC', 'style' => 'list', 'show_count' => 0, 'hide_empty' => 1, 'use_desc_for_title' => 1, 'child_of' => 0, 'feed' => '', 'feed_type' => '', 'feed_image' => '', 'exclude' => '', 'exclude_tree' => '', 'current_category' => 0, 'hierarchical' => true, 'title_li' => __('Categories'), 'hide_title_if_empty' => false, 'echo' => 1, 'depth' => 0, 'separator' => '<br />', 'taxonomy' => 'category');
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    // Descendants of exclusions should be excluded too.
    if (true == $r['hierarchical']) {
        $exclude_tree = array();
        if ($r['exclude_tree']) {
            $exclude_tree = array_merge($exclude_tree, (array) $r['exclude_tree']);
        }
        if ($r['exclude']) {
            $exclude_tree = array_merge($exclude_tree, (array) $r['exclude']);
        }
        $r['exclude_tree'] = $exclude_tree;
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    if (!taxonomy_exists($r['taxonomy'])) {
        return false;
    }
    $show_option_all = $r['show_option_all'];
    $show_option_none = $r['show_option_none'];
    $categories = get_categories($r);
    $output = '';
    if ($r['title_li'] && 'list' == $r['style'] && (!empty($categories) || !$r['hide_title_if_empty'])) {
        $output = '<li class="' . esc_attr($r['class']) . '">' . $r['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $r['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($r['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type) && !in_array('page', $taxonomy_object->object_type)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the posts page.
            if (!$posts_page) {
                if ('page' == get_option('show_on_front') && get_option('page_for_posts')) {
                    $posts_page = get_permalink(get_option('page_for_posts'));
                } else {
                    $posts_page = home_url('/');
                }
            }
            $posts_page = esc_url($posts_page);
            if ('list' == $r['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($r['hierarchical']) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($r['title_li'] && 'list' == $r['style']) {
        $output .= '</ul></li>';
    }
    /**
     * Filter the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($r['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 4.3

/**
 * Display or retrieve the HTML list of categories.
 *
 * The list of arguments is below:
 *     'show_option_all' (string) - Text to display for showing all categories.
 *     'orderby' (string) default is 'ID' - What column to use for ordering the
 * categories.
 *     'order' (string) default is 'ASC' - What direction to order categories.
 *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
 * in the category.
 *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
 * don't have any posts attached to them.
 *     'use_desc_for_title' (bool|int) default is 1 - Whether to use the
 * category description as the title attribute.
 *     'feed' - See {@link get_categories()}.
 *     'feed_type' - See {@link get_categories()}.
 *     'feed_image' - See {@link get_categories()}.
 *     'child_of' (int) default is 0 - See {@link get_categories()}.
 *     'exclude' (string) - See {@link get_categories()}.
 *     'exclude_tree' (string) - See {@link get_categories()}.
 *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
 *     'current_category' (int) - See {@link get_categories()}.
 *     'hierarchical' (bool) - See {@link get_categories()}.
 *     'title_li' (string) - See {@link get_categories()}.
 *     'depth' (int) - The max depth.
 *
 * @since 2.1.0
 *
 * @param string|array $args Optional. Override default arguments.
 * @return false|string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('show_option_all' => '', 'show_option_none' => __('No categories'), 'orderby' => 'name', 'order' => 'ASC', 'style' => 'list', 'show_count' => 0, 'hide_empty' => 1, 'use_desc_for_title' => 1, 'child_of' => 0, 'feed' => '', 'feed_type' => '', 'feed_image' => '', 'exclude' => '', 'exclude_tree' => '', 'current_category' => 0, 'hierarchical' => true, 'title_li' => __('Categories'), 'echo' => 1, 'depth' => 0, 'taxonomy' => 'category');
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    if (true == $r['hierarchical']) {
        $r['exclude_tree'] = $r['exclude'];
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    if (!taxonomy_exists($r['taxonomy'])) {
        return false;
    }
    $show_option_all = $r['show_option_all'];
    $show_option_none = $r['show_option_none'];
    $categories = get_categories($r);
    $output = '';
    if ($r['title_li'] && 'list' == $r['style']) {
        $output = '<li class="' . esc_attr($r['class']) . '">' . $r['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $r['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = '';
            // For taxonomies that belong only to custom post types, point to a valid archive.
            $taxonomy_object = get_taxonomy($r['taxonomy']);
            if (!in_array('post', $taxonomy_object->object_type) && !in_array('page', $taxonomy_object->object_type)) {
                foreach ($taxonomy_object->object_type as $object_type) {
                    $_object_type = get_post_type_object($object_type);
                    // Grab the first one.
                    if (!empty($_object_type->has_archive)) {
                        $posts_page = get_post_type_archive_link($object_type);
                        break;
                    }
                }
            }
            // Fallback for the 'All' link is the front page.
            if (!$posts_page) {
                $posts_page = ('page' == get_option('show_on_front') && get_option('page_for_posts')) ? get_permalink(get_option('page_for_posts')) : home_url('/');
            }
            $posts_page = esc_url($posts_page);
            if ('list' == $r['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($r['hierarchical']) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($r['title_li'] && 'list' == $r['style']) {
        $output .= '</ul></li>';
    }
    /**
     * Filter the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($r['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 4.1

/**
 * Display or retrieve the HTML list of categories.
 *
 * The list of arguments is below:
 *     'show_option_all' (string) - Text to display for showing all categories.
 *     'orderby' (string) default is 'ID' - What column to use for ordering the
 * categories.
 *     'order' (string) default is 'ASC' - What direction to order categories.
 *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
 * in the category.
 *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
 * don't have any posts attached to them.
 *     'use_desc_for_title' (bool|int) default is 1 - Whether to use the
 * category description as the title attribute.
 *     'feed' - See {@link get_categories()}.
 *     'feed_type' - See {@link get_categories()}.
 *     'feed_image' - See {@link get_categories()}.
 *     'child_of' (int) default is 0 - See {@link get_categories()}.
 *     'exclude' (string) - See {@link get_categories()}.
 *     'exclude_tree' (string) - See {@link get_categories()}.
 *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
 *     'current_category' (int) - See {@link get_categories()}.
 *     'hierarchical' (bool) - See {@link get_categories()}.
 *     'title_li' (string) - See {@link get_categories()}.
 *     'depth' (int) - The max depth.
 *
 * @since 2.1.0
 *
 * @param string|array $args Optional. Override default arguments.
 * @return false|null|string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('show_option_all' => '', 'show_option_none' => __('No categories'), 'orderby' => 'name', 'order' => 'ASC', 'style' => 'list', 'show_count' => 0, 'hide_empty' => 1, 'use_desc_for_title' => 1, 'child_of' => 0, 'feed' => '', 'feed_type' => '', 'feed_image' => '', 'exclude' => '', 'exclude_tree' => '', 'current_category' => 0, 'hierarchical' => true, 'title_li' => __('Categories'), 'echo' => 1, 'depth' => 0, 'taxonomy' => 'category');
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    if (true == $r['hierarchical']) {
        $r['exclude_tree'] = $r['exclude'];
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    if (!taxonomy_exists($r['taxonomy'])) {
        return false;
    }
    $show_option_all = $r['show_option_all'];
    $show_option_none = $r['show_option_none'];
    $categories = get_categories($r);
    $output = '';
    if ($r['title_li'] && 'list' == $r['style']) {
        $output = '<li class="' . esc_attr($r['class']) . '">' . $r['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $r['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = ('page' == get_option('show_on_front') && get_option('page_for_posts')) ? get_permalink(get_option('page_for_posts')) : home_url('/');
            $posts_page = esc_url($posts_page);
            if ('list' == $r['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($r['hierarchical']) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($r['title_li'] && 'list' == $r['style']) {
        $output .= '</ul></li>';
    }
    /**
     * Filter the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($r['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 4.0

/**
 * Display or retrieve the HTML list of categories.
 *
 * The list of arguments is below:
 *     'show_option_all' (string) - Text to display for showing all categories.
 *     'orderby' (string) default is 'ID' - What column to use for ordering the
 * categories.
 *     'order' (string) default is 'ASC' - What direction to order categories.
 *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
 * in the category.
 *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
 * don't have any posts attached to them.
 *     'use_desc_for_title' (bool|int) default is 1 - Whether to use the
 * category description as the title attribute.
 *     'feed' - See {@link get_categories()}.
 *     'feed_type' - See {@link get_categories()}.
 *     'feed_image' - See {@link get_categories()}.
 *     'child_of' (int) default is 0 - See {@link get_categories()}.
 *     'exclude' (string) - See {@link get_categories()}.
 *     'exclude_tree' (string) - See {@link get_categories()}.
 *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
 *     'current_category' (int) - See {@link get_categories()}.
 *     'hierarchical' (bool) - See {@link get_categories()}.
 *     'title_li' (string) - See {@link get_categories()}.
 *     'depth' (int) - The max depth.
 *
 * @since 2.1.0
 *
 * @param string|array $args Optional. Override default arguments.
 * @return string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('show_option_all' => '', 'show_option_none' => __('No categories'), 'orderby' => 'name', 'order' => 'ASC', 'style' => 'list', 'show_count' => 0, 'hide_empty' => 1, 'use_desc_for_title' => 1, 'child_of' => 0, 'feed' => '', 'feed_type' => '', 'feed_image' => '', 'exclude' => '', 'exclude_tree' => '', 'current_category' => 0, 'hierarchical' => true, 'title_li' => __('Categories'), 'echo' => 1, 'depth' => 0, 'taxonomy' => 'category');
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    if (true == $r['hierarchical']) {
        $r['exclude_tree'] = $r['exclude'];
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    if (!taxonomy_exists($r['taxonomy'])) {
        return false;
    }
    $show_option_all = $r['show_option_all'];
    $show_option_none = $r['show_option_none'];
    $categories = get_categories($r);
    $output = '';
    if ($r['title_li'] && 'list' == $r['style']) {
        $output = '<li class="' . esc_attr($r['class']) . '">' . $r['title_li'] . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $r['style']) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = ('page' == get_option('show_on_front') && get_option('page_for_posts')) ? get_permalink(get_option('page_for_posts')) : home_url('/');
            $posts_page = esc_url($posts_page);
            if ('list' == $r['style']) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($r['hierarchical']) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
            // Flat.
        }
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($r['title_li'] && 'list' == $r['style']) {
        $output .= '</ul></li>';
    }
    /**
     * Filter the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $html = apply_filters('wp_list_categories', $output, $args);
    if ($r['echo']) {
        echo $html;
    } else {
        return $html;
    }
}

WordPress Version: 3.9

/**
 * Display or retrieve the HTML list of categories.
 *
 * The list of arguments is below:
 *     'show_option_all' (string) - Text to display for showing all categories.
 *     'orderby' (string) default is 'ID' - What column to use for ordering the
 * categories.
 *     'order' (string) default is 'ASC' - What direction to order categories.
 *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
 * in the category.
 *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
 * don't have any posts attached to them.
 *     'use_desc_for_title' (bool|int) default is 1 - Whether to use the
 * description instead of the category title.
 *     'feed' - See {@link get_categories()}.
 *     'feed_type' - See {@link get_categories()}.
 *     'feed_image' - See {@link get_categories()}.
 *     'child_of' (int) default is 0 - See {@link get_categories()}.
 *     'exclude' (string) - See {@link get_categories()}.
 *     'exclude_tree' (string) - See {@link get_categories()}.
 *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
 *     'current_category' (int) - See {@link get_categories()}.
 *     'hierarchical' (bool) - See {@link get_categories()}.
 *     'title_li' (string) - See {@link get_categories()}.
 *     'depth' (int) - The max depth.
 *
 * @since 2.1.0
 *
 * @param string|array $args Optional. Override default arguments.
 * @return string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('show_option_all' => '', 'show_option_none' => __('No categories'), 'orderby' => 'name', 'order' => 'ASC', 'style' => 'list', 'show_count' => 0, 'hide_empty' => 1, 'use_desc_for_title' => 1, 'child_of' => 0, 'feed' => '', 'feed_type' => '', 'feed_image' => '', 'exclude' => '', 'exclude_tree' => '', 'current_category' => 0, 'hierarchical' => true, 'title_li' => __('Categories'), 'echo' => 1, 'depth' => 0, 'taxonomy' => 'category');
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    if (true == $r['hierarchical']) {
        $r['exclude_tree'] = $r['exclude'];
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    extract($r);
    if (!taxonomy_exists($taxonomy)) {
        return false;
    }
    $categories = get_categories($r);
    $output = '';
    if ($title_li && 'list' == $style) {
        $output = '<li class="' . esc_attr($class) . '">' . $title_li . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $style) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = ('page' == get_option('show_on_front') && get_option('page_for_posts')) ? get_permalink(get_option('page_for_posts')) : home_url('/');
            $posts_page = esc_url($posts_page);
            if ('list' == $style) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($hierarchical) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
        }
        // Flat.
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($title_li && 'list' == $style) {
        $output .= '</ul></li>';
    }
    /**
     * Filter the HTML output of a taxonomy list.
     *
     * @since 2.1.0
     *
     * @param string $output HTML output.
     * @param array  $args   An array of taxonomy-listing arguments.
     */
    $output = apply_filters('wp_list_categories', $output, $args);
    if ($echo) {
        echo $output;
    } else {
        return $output;
    }
}

WordPress Version: 3.8

/**
 * Display or retrieve the HTML list of categories.
 *
 * The list of arguments is below:
 *     'show_option_all' (string) - Text to display for showing all categories.
 *     'orderby' (string) default is 'ID' - What column to use for ordering the
 * categories.
 *     'order' (string) default is 'ASC' - What direction to order categories.
 *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
 * in the category.
 *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
 * don't have any posts attached to them.
 *     'use_desc_for_title' (bool|int) default is 1 - Whether to use the
 * description instead of the category title.
 *     'feed' - See {@link get_categories()}.
 *     'feed_type' - See {@link get_categories()}.
 *     'feed_image' - See {@link get_categories()}.
 *     'child_of' (int) default is 0 - See {@link get_categories()}.
 *     'exclude' (string) - See {@link get_categories()}.
 *     'exclude_tree' (string) - See {@link get_categories()}.
 *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
 *     'current_category' (int) - See {@link get_categories()}.
 *     'hierarchical' (bool) - See {@link get_categories()}.
 *     'title_li' (string) - See {@link get_categories()}.
 *     'depth' (int) - The max depth.
 *
 * @since 2.1.0
 *
 * @param string|array $args Optional. Override default arguments.
 * @return string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('show_option_all' => '', 'show_option_none' => __('No categories'), 'orderby' => 'name', 'order' => 'ASC', 'style' => 'list', 'show_count' => 0, 'hide_empty' => 1, 'use_desc_for_title' => 1, 'child_of' => 0, 'feed' => '', 'feed_type' => '', 'feed_image' => '', 'exclude' => '', 'exclude_tree' => '', 'current_category' => 0, 'hierarchical' => true, 'title_li' => __('Categories'), 'echo' => 1, 'depth' => 0, 'taxonomy' => 'category');
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    if (true == $r['hierarchical']) {
        $r['exclude_tree'] = $r['exclude'];
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    extract($r);
    if (!taxonomy_exists($taxonomy)) {
        return false;
    }
    $categories = get_categories($r);
    $output = '';
    if ($title_li && 'list' == $style) {
        $output = '<li class="' . esc_attr($class) . '">' . $title_li . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $style) {
                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = ('page' == get_option('show_on_front') && get_option('page_for_posts')) ? get_permalink(get_option('page_for_posts')) : home_url('/');
            $posts_page = esc_url($posts_page);
            if ('list' == $style) {
                $output .= "<li class='cat-item-all'><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($hierarchical) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
        }
        // Flat.
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($title_li && 'list' == $style) {
        $output .= '</ul></li>';
    }
    $output = apply_filters('wp_list_categories', $output, $args);
    if ($echo) {
        echo $output;
    } else {
        return $output;
    }
}

WordPress Version: 3.7

/**
 * Display or retrieve the HTML list of categories.
 *
 * The list of arguments is below:
 *     'show_option_all' (string) - Text to display for showing all categories.
 *     'orderby' (string) default is 'ID' - What column to use for ordering the
 * categories.
 *     'order' (string) default is 'ASC' - What direction to order categories.
 *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
 * in the category.
 *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
 * don't have any posts attached to them.
 *     'use_desc_for_title' (bool|int) default is 1 - Whether to use the
 * description instead of the category title.
 *     'feed' - See {@link get_categories()}.
 *     'feed_type' - See {@link get_categories()}.
 *     'feed_image' - See {@link get_categories()}.
 *     'child_of' (int) default is 0 - See {@link get_categories()}.
 *     'exclude' (string) - See {@link get_categories()}.
 *     'exclude_tree' (string) - See {@link get_categories()}.
 *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
 *     'current_category' (int) - See {@link get_categories()}.
 *     'hierarchical' (bool) - See {@link get_categories()}.
 *     'title_li' (string) - See {@link get_categories()}.
 *     'depth' (int) - The max depth.
 *
 * @since 2.1.0
 *
 * @param string|array $args Optional. Override default arguments.
 * @return string HTML content only if 'echo' argument is 0.
 */
function wp_list_categories($args = '')
{
    $defaults = array('show_option_all' => '', 'show_option_none' => __('No categories'), 'orderby' => 'name', 'order' => 'ASC', 'style' => 'list', 'show_count' => 0, 'hide_empty' => 1, 'use_desc_for_title' => 1, 'child_of' => 0, 'feed' => '', 'feed_type' => '', 'feed_image' => '', 'exclude' => '', 'exclude_tree' => '', 'current_category' => 0, 'hierarchical' => true, 'title_li' => __('Categories'), 'echo' => 1, 'depth' => 0, 'taxonomy' => 'category');
    $r = wp_parse_args($args, $defaults);
    if (!isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical']) {
        $r['pad_counts'] = true;
    }
    if (true == $r['hierarchical']) {
        $r['exclude_tree'] = $r['exclude'];
        $r['exclude'] = '';
    }
    if (!isset($r['class'])) {
        $r['class'] = ('category' == $r['taxonomy']) ? 'categories' : $r['taxonomy'];
    }
    extract($r);
    if (!taxonomy_exists($taxonomy)) {
        return false;
    }
    $categories = get_categories($r);
    $output = '';
    if ($title_li && 'list' == $style) {
        $output = '<li class="' . esc_attr($class) . '">' . $title_li . '<ul>';
    }
    if (empty($categories)) {
        if (!empty($show_option_none)) {
            if ('list' == $style) {
                $output .= '<li>' . $show_option_none . '</li>';
            } else {
                $output .= $show_option_none;
            }
        }
    } else {
        if (!empty($show_option_all)) {
            $posts_page = ('page' == get_option('show_on_front') && get_option('page_for_posts')) ? get_permalink(get_option('page_for_posts')) : home_url('/');
            $posts_page = esc_url($posts_page);
            if ('list' == $style) {
                $output .= "<li><a href='{$posts_page}'>{$show_option_all}</a></li>";
            } else {
                $output .= "<a href='{$posts_page}'>{$show_option_all}</a>";
            }
        }
        if (empty($r['current_category']) && (is_category() || is_tax() || is_tag())) {
            $current_term_object = get_queried_object();
            if ($current_term_object && $r['taxonomy'] === $current_term_object->taxonomy) {
                $r['current_category'] = get_queried_object_id();
            }
        }
        if ($hierarchical) {
            $depth = $r['depth'];
        } else {
            $depth = -1;
        }
        // Flat.
        $output .= walk_category_tree($categories, $depth, $r);
    }
    if ($title_li && 'list' == $style) {
        $output .= '</ul></li>';
    }
    $output = apply_filters('wp_list_categories', $output, $args);
    if ($echo) {
        echo $output;
    } else {
        return $output;
    }
}