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