* Taxonomy API: Core category-specific template tags
* Retrieves category link URL.
* @param int|object $category Category ID or object.
* @return string Link on success, empty string if category does not exist.
function get_category_link( $category ) {
if ( ! is_object( $category ) ) {
$category = (int) $category;
$category = get_term_link( $category );
if ( is_wp_error( $category ) ) {
* Retrieves category parents with separator.
* @since 4.8.0 The `$visited` parameter was deprecated and renamed to `$deprecated`.
* @param int $category_id Category ID.
* @param bool $link Optional. Whether to format with link. Default false.
* @param string $separator Optional. How to separate categories. Default '/'.
* @param bool $nicename Optional. Whether to use nice name for display. Default false.
* @param array $deprecated Not used.
* @return string|WP_Error A list of category parents on success, WP_Error on failure.
function get_category_parents( $category_id, $link = false, $separator = '/', $nicename = false, $deprecated = array() ) {
if ( ! empty( $deprecated ) ) {
_deprecated_argument( __FUNCTION__, '4.8.0' );
$format = $nicename ? 'slug' : 'name';
'separator' => $separator,
return get_term_parents_list( $category_id, 'category', $args );
* Retrieves post categories.
* This tag may be used outside The Loop by passing a post ID as the parameter.
* Note: This function only returns results from the default "category" taxonomy.
* For custom taxonomies use get_the_terms().
* @param int|false $post_id Optional. The post ID. Defaults to current post ID.
* @return WP_Term[] Array of WP_Term objects, one for each category assigned to the post.
function get_the_category( $post_id = false ) {
$categories = get_the_terms( $post_id, 'category' );
if ( ! $categories || is_wp_error( $categories ) ) {
$categories = array_values( $categories );
foreach ( array_keys( $categories ) as $key ) {
_make_cat_compat( $categories[ $key ] );
* Filters the array of categories to return for a post.
* @since 4.4.0 Added the `$post_id` parameter.
* @param WP_Term[] $categories An array of categories to return for the post.
* @param int|false $post_id The post ID.
return apply_filters( 'get_the_categories', $categories, $post_id );
* Retrieves category name based on category ID.
* @param int $cat_id Category ID.
* @return string|WP_Error Category name on success, WP_Error on failure.
function get_the_category_by_ID( $cat_id ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
$category = get_term( $cat_id );
if ( is_wp_error( $category ) ) {
return ( $category ) ? $category->name : '';
* Retrieves category list for a post in either HTML list or custom format.
* Generally used for quick, delimited (e.g. comma-separated) lists of categories,
* as part of a post entry meta.
* For a more powerful, list-based function, see wp_list_categories().
* @see wp_list_categories()
* @global WP_Rewrite $wp_rewrite WordPress rewrite component.
* @param string $separator Optional. Separator between the categories. By default, the links are placed
* in an unordered list. An empty string will result in the default behavior.
* @param string $parents Optional. How to display the parents. Accepts 'multiple', 'single', or empty.
* @param int|false $post_id Optional. ID of the post to retrieve categories for. Defaults to the current post.
* @return string Category list for a post.
function get_the_category_list( $separator = '', $parents = '', $post_id = false ) {
if ( ! is_object_in_taxonomy( get_post_type( $post_id ), 'category' ) ) {
/** This filter is documented in wp-includes/category-template.php */
return apply_filters( 'the_category', '', $separator, $parents );
* Filters the categories before building the category list.
* @param WP_Term[] $categories An array of the post's categories.
* @param int|false $post_id ID of the post to retrieve categories for.
* When `false`, defaults to the current post in the loop.
$categories = apply_filters( 'the_category_list', get_the_category( $post_id ), $post_id );
if ( empty( $categories ) ) {
/** This filter is documented in wp-includes/category-template.php */
return apply_filters( 'the_category', __( 'Uncategorized' ), $separator, $parents );
$rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';
if ( '' === $separator ) {
$thelist .= '<ul class="post-categories">';
foreach ( $categories as $category ) {
switch ( strtolower( $parents ) ) {
if ( $category->parent ) {
$thelist .= get_category_parents( $category->parent, true, $separator );
$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>';
$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';
if ( $category->parent ) {
$thelist .= get_category_parents( $category->parent, false, $separator );
$thelist .= $category->name . '</a></li>';
$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>';
foreach ( $categories as $category ) {
switch ( strtolower( $parents ) ) {
if ( $category->parent ) {
$thelist .= get_category_parents( $category->parent, true, $separator );
$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>';
$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';
if ( $category->parent ) {
$thelist .= get_category_parents( $category->parent, false, $separator );
$thelist .= "$category->name</a>";
$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>';
* Filters the category or list of categories.
* @param string $thelist List of categories for the current post.
* @param string $separator Separator used between the categories.
* @param string $parents How to display the category parents. Accepts 'multiple',
return apply_filters( 'the_category', $thelist, $separator, $parents );
* Checks if the current post is within any of the given categories.
* The given categories are checked against the post's categories' term_ids, names and slugs.
* Categories given as integers will only be checked against the post's categories' term_ids.
* Prior to v2.5 of WordPress, category names were not supported.
* Prior to v2.7, category slugs were not supported.
* Prior to v2.7, only one category could be compared: in_category( $single_category ).
* Prior to v2.7, this function could only be used in the WordPress Loop.
* As of 2.7, the function can be used anywhere if it is provided a post ID or post object.
* For more information on this and similar theme functions, check out
* the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
* Conditional Tags} article in the Theme Developer Handbook.
* @since 2.7.0 The `$post` parameter was added.
* @param int|string|int[]|string[] $category Category ID, name, slug, or array of such
* @param int|null|WP_Post $post Optional. Post to check. Defaults to the current post.
* @return bool True if the current post is in any of the given categories.
function in_category( $category, $post = null ) {
if ( empty( $category ) ) {
return has_category( $category, $post );
* Displays category list for a post in either HTML list or custom format.
* @param string $separator Optional. Separator between the categories. By default, the links are placed
* in an unordered list. An empty string will result in the default behavior.
* @param string $parents Optional. How to display the parents. Accepts 'multiple', 'single', or empty.
* @param int|false $post_id Optional. ID of the post to retrieve categories for. Defaults to the current post.
function the_category( $separator = '', $parents = '', $post_id = false ) {
echo get_the_category_list( $separator, $parents, $post_id );
* Retrieves category description.
* @param int $category Optional. Category ID. Defaults to the current category ID.
* @return string Category description, if available.
function category_description( $category = 0 ) {
return term_description( $category );
* Displays or retrieves the HTML dropdown list of categories.
* The 'hierarchical' argument, which is disabled by default, will override the
* depth argument, unless it is true. When the argument is false, it will
* display all of the categories. When it is enabled it will use the value in
* @since 4.2.0 Introduced the `value_field` argument.
* @since 4.6.0 Introduced the `required` argument.
* @since 6.1.0 Introduced the `aria_describedby` argument.
* @param array|string $args {
* Optional. Array or string of arguments to generate a categories drop-down element. See WP_Term_Query::__construct()
* for information on additional accepted arguments.
* @type string $show_option_all Text to display for showing all categories. Default empty.
* @type string $show_option_none Text to display for showing no categories. Default empty.
* @type string $option_none_value Value to use when no category is selected. Default empty.
* @type string $orderby Which column to use for ordering categories. See get_terms() for a list
* of accepted values. Default 'id' (term_id).
* @type bool $pad_counts See get_terms() for an argument description. Default false.
* @type bool|int $show_count Whether to include post counts. Accepts 0, 1, or their bool equivalents.
* @type bool|int $echo Whether to echo or return the generated markup. Accepts 0, 1, or their
* bool equivalents. Default 1.
* @type bool|int $hierarchical Whether to traverse the taxonomy hierarchy. Accepts 0, 1, or their bool
* equivalents. Default 0.
* @type int $depth Maximum depth. Default 0.
* @type int $tab_index Tab index for the select element. Default 0 (no tabindex).
* @type string $name Value for the 'name' attribute of the select element. Default 'cat'.
* @type string $id Value for the 'id' attribute of the select element. Defaults to the value
* @type string $class Value for the 'class' attribute of the select element. Default 'postform'.
* @type int|string $selected Value of the option that should be selected. Default 0.
* @type string $value_field Term field that should be used to populate the 'value' attribute
* of the option elements. Accepts any valid term field: 'term_id', 'name',
* 'slug', 'term_group', 'term_taxonomy_id', 'taxonomy', 'description',
* 'parent', 'count'. Default 'term_id'.
* @type string|array $taxonomy Name of the taxonomy or taxonomies to retrieve. Default 'category'.
* @type bool $hide_if_empty True to skip generating markup if no categories are found.
* Default false (create select element even if no categories are found).
* @type bool $required Whether the `<select>` element should have the HTML5 'required' attribute.
* @type Walker $walker Walker object to use to build the output. Default empty which results in a
* Walker_CategoryDropdown instance being used.
* @type string $aria_describedby The 'id' of an element that contains descriptive text for the select.
* @return string HTML dropdown list of categories.
function wp_dropdown_categories( $args = '' ) {
'show_option_none' => '',
'taxonomy' => 'category',
'hide_if_empty' => false,
'option_none_value' => -1,
'value_field' => 'term_id',
'aria_describedby' => '',
$defaults['selected'] = ( is_category() ) ? get_query_var( 'cat' ) : 0;
if ( isset( $args['type'] ) && 'link' === $args['type'] ) {
/* translators: 1: "type => link", 2: "taxonomy => link_category" */
__( '%1$s is deprecated. Use %2$s instead.' ),
'<code>type => link</code>',
'<code>taxonomy => link_category</code>'
$args['taxonomy'] = 'link_category';
// Parse incoming $args into an array and merge it with $defaults.
$parsed_args = wp_parse_args( $args, $defaults );
$option_none_value = $parsed_args['option_none_value'];
if ( ! isset( $parsed_args['pad_counts'] ) && $parsed_args['show_count'] && $parsed_args['hierarchical'] ) {
$parsed_args['pad_counts'] = true;
$tab_index = $parsed_args['tab_index'];
$tab_index_attribute = '';
if ( (int) $tab_index > 0 ) {
$tab_index_attribute = " tabindex=\"$tab_index\"";
// Avoid clashes with the 'name' param of get_terms().
$get_terms_args = $parsed_args;
unset( $get_terms_args['name'] );
$categories = get_terms( $get_terms_args );
$name = esc_attr( $parsed_args['name'] );
$class = esc_attr( $parsed_args['class'] );
$id = $parsed_args['id'] ? esc_attr( $parsed_args['id'] ) : $name;
$required = $parsed_args['required'] ? 'required' : '';
$aria_describedby_attribute = $parsed_args['aria_describedby'] ? ' aria-describedby="' . esc_attr( $parsed_args['aria_describedby'] ) . '"' : '';
if ( ! $parsed_args['hide_if_empty'] || ! empty( $categories ) ) {
$output = "<select $required name='$name' id='$id' class='$class'$tab_index_attribute$aria_describedby_attribute>\n";
if ( empty( $categories ) && ! $parsed_args['hide_if_empty'] && ! empty( $parsed_args['show_option_none'] ) ) {
* Filters a taxonomy drop-down display element.
* A variety of taxonomy drop-down display elements can be modified
* just prior to display via this filter. Filterable arguments include
* 'show_option_none', 'show_option_all', and various forms of the
* @see wp_dropdown_categories()
* @param string $element Category name.
* @param WP_Term|null $category The category object, or null if there's no corresponding category.
$show_option_none = apply_filters( 'list_cats', $parsed_args['show_option_none'], null );
$output .= "\t<option value='" . esc_attr( $option_none_value ) . "' selected='selected'>$show_option_none</option>\n";
if ( ! empty( $categories ) ) {
if ( $parsed_args['show_option_all'] ) {
/** This filter is documented in wp-includes/category-template.php */
$show_option_all = apply_filters( 'list_cats', $parsed_args['show_option_all'], null );
$selected = ( '0' === (string) $parsed_args['selected'] ) ? " selected='selected'" : '';
$output .= "\t<option value='0'$selected>$show_option_all</option>\n";
if ( $parsed_args['show_option_none'] ) {
/** This filter is documented in wp-includes/category-template.php */
$show_option_none = apply_filters( 'list_cats', $parsed_args['show_option_none'], null );
$selected = selected( $option_none_value, $parsed_args['selected'], false );
$output .= "\t<option value='" . esc_attr( $option_none_value ) . "'$selected>$show_option_none</option>\n";
if ( $parsed_args['hierarchical'] ) {
$depth = $parsed_args['depth']; // Walk the full depth.
$output .= walk_category_dropdown_tree( $categories, $depth, $parsed_args );
if ( ! $parsed_args['hide_if_empty'] || ! empty( $categories ) ) {
$output .= "</select>\n";
* Filters the taxonomy drop-down output.
* @param string $output HTML output.
* @param array $parsed_args Arguments used to build the drop-down.
$output = apply_filters( 'wp_dropdown_cats', $output, $parsed_args );
if ( $parsed_args['echo'] ) {
* Displays or retrieves the HTML list of categories.
* @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