[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Taxonomy API: Core category-specific template tags 4 * 5 * @package WordPress 6 * @subpackage Template 7 * @since 1.2.0 8 */ 9 10 /** 11 * Retrieves category link URL. 12 * 13 * @since 1.0.0 14 * 15 * @see get_term_link() 16 * 17 * @param int|object $category Category ID or object. 18 * @return string Link on success, empty string if category does not exist. 19 */ 20 function get_category_link( $category ) { 21 if ( ! is_object( $category ) ) { 22 $category = (int) $category; 23 } 24 25 $category = get_term_link( $category ); 26 27 if ( is_wp_error( $category ) ) { 28 return ''; 29 } 30 31 return $category; 32 } 33 34 /** 35 * Retrieves category parents with separator. 36 * 37 * @since 1.2.0 38 * @since 4.8.0 The `$visited` parameter was deprecated and renamed to `$deprecated`. 39 * 40 * @param int $category_id Category ID. 41 * @param bool $link Optional. Whether to format with link. Default false. 42 * @param string $separator Optional. How to separate categories. Default '/'. 43 * @param bool $nicename Optional. Whether to use nice name for display. Default false. 44 * @param array $deprecated Not used. 45 * @return string|WP_Error A list of category parents on success, WP_Error on failure. 46 */ 47 function get_category_parents( $category_id, $link = false, $separator = '/', $nicename = false, $deprecated = array() ) { 48 49 if ( ! empty( $deprecated ) ) { 50 _deprecated_argument( __FUNCTION__, '4.8.0' ); 51 } 52 53 $format = $nicename ? 'slug' : 'name'; 54 55 $args = array( 56 'separator' => $separator, 57 'link' => $link, 58 'format' => $format, 59 ); 60 61 return get_term_parents_list( $category_id, 'category', $args ); 62 } 63 64 /** 65 * Retrieves post categories. 66 * 67 * This tag may be used outside The Loop by passing a post ID as the parameter. 68 * 69 * Note: This function only returns results from the default "category" taxonomy. 70 * For custom taxonomies use get_the_terms(). 71 * 72 * @since 0.71 73 * 74 * @param int $post_id Optional. The post ID. Defaults to current post ID. 75 * @return WP_Term[] Array of WP_Term objects, one for each category assigned to the post. 76 */ 77 function get_the_category( $post_id = false ) { 78 $categories = get_the_terms( $post_id, 'category' ); 79 if ( ! $categories || is_wp_error( $categories ) ) { 80 $categories = array(); 81 } 82 83 $categories = array_values( $categories ); 84 85 foreach ( array_keys( $categories ) as $key ) { 86 _make_cat_compat( $categories[ $key ] ); 87 } 88 89 /** 90 * Filters the array of categories to return for a post. 91 * 92 * @since 3.1.0 93 * @since 4.4.0 Added `$post_id` parameter. 94 * 95 * @param WP_Term[] $categories An array of categories to return for the post. 96 * @param int|false $post_id ID of the post. 97 */ 98 return apply_filters( 'get_the_categories', $categories, $post_id ); 99 } 100 101 /** 102 * Retrieves category name based on category ID. 103 * 104 * @since 0.71 105 * 106 * @param int $cat_id Category ID. 107 * @return string|WP_Error Category name on success, WP_Error on failure. 108 */ 109 function get_the_category_by_ID( $cat_id ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid 110 $cat_id = (int) $cat_id; 111 $category = get_term( $cat_id ); 112 113 if ( is_wp_error( $category ) ) { 114 return $category; 115 } 116 117 return ( $category ) ? $category->name : ''; 118 } 119 120 /** 121 * Retrieves category list for a post in either HTML list or custom format. 122 * 123 * Generally used for quick, delimited (e.g. comma-separated) lists of categories, 124 * as part of a post entry meta. 125 * 126 * For a more powerful, list-based function, see wp_list_categories(). 127 * 128 * @since 1.5.1 129 * 130 * @see wp_list_categories() 131 * 132 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 133 * 134 * @param string $separator Optional. Separator between the categories. By default, the links are placed 135 * in an unordered list. An empty string will result in the default behavior. 136 * @param string $parents Optional. How to display the parents. 137 * @param int $post_id Optional. Post ID to retrieve categories. 138 * @return string Category list for a post. 139 */ 140 function get_the_category_list( $separator = '', $parents = '', $post_id = false ) { 141 global $wp_rewrite; 142 143 if ( ! is_object_in_taxonomy( get_post_type( $post_id ), 'category' ) ) { 144 /** This filter is documented in wp-includes/category-template.php */ 145 return apply_filters( 'the_category', '', $separator, $parents ); 146 } 147 148 /** 149 * Filters the categories before building the category list. 150 * 151 * @since 4.4.0 152 * 153 * @param WP_Term[] $categories An array of the post's categories. 154 * @param int|bool $post_id ID of the post we're retrieving categories for. 155 * When `false`, we assume the current post in the loop. 156 */ 157 $categories = apply_filters( 'the_category_list', get_the_category( $post_id ), $post_id ); 158 159 if ( empty( $categories ) ) { 160 /** This filter is documented in wp-includes/category-template.php */ 161 return apply_filters( 'the_category', __( 'Uncategorized' ), $separator, $parents ); 162 } 163 164 $rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"'; 165 166 $thelist = ''; 167 if ( '' === $separator ) { 168 $thelist .= '<ul class="post-categories">'; 169 foreach ( $categories as $category ) { 170 $thelist .= "\n\t<li>"; 171 switch ( strtolower( $parents ) ) { 172 case 'multiple': 173 if ( $category->parent ) { 174 $thelist .= get_category_parents( $category->parent, true, $separator ); 175 } 176 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>'; 177 break; 178 case 'single': 179 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>'; 180 if ( $category->parent ) { 181 $thelist .= get_category_parents( $category->parent, false, $separator ); 182 } 183 $thelist .= $category->name . '</a></li>'; 184 break; 185 case '': 186 default: 187 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>'; 188 } 189 } 190 $thelist .= '</ul>'; 191 } else { 192 $i = 0; 193 foreach ( $categories as $category ) { 194 if ( 0 < $i ) { 195 $thelist .= $separator; 196 } 197 switch ( strtolower( $parents ) ) { 198 case 'multiple': 199 if ( $category->parent ) { 200 $thelist .= get_category_parents( $category->parent, true, $separator ); 201 } 202 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>'; 203 break; 204 case 'single': 205 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>'; 206 if ( $category->parent ) { 207 $thelist .= get_category_parents( $category->parent, false, $separator ); 208 } 209 $thelist .= "$category->name</a>"; 210 break; 211 case '': 212 default: 213 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>'; 214 } 215 ++$i; 216 } 217 } 218 219 /** 220 * Filters the category or list of categories. 221 * 222 * @since 1.2.0 223 * 224 * @param string $thelist List of categories for the current post. 225 * @param string $separator Separator used between the categories. 226 * @param string $parents How to display the category parents. Accepts 'multiple', 227 * 'single', or empty. 228 */ 229 return apply_filters( 'the_category', $thelist, $separator, $parents ); 230 } 231 232 /** 233 * Checks if the current post is within any of the given categories. 234 * 235 * The given categories are checked against the post's categories' term_ids, names and slugs. 236 * Categories given as integers will only be checked against the post's categories' term_ids. 237 * 238 * Prior to v2.5 of WordPress, category names were not supported. 239 * Prior to v2.7, category slugs were not supported. 240 * Prior to v2.7, only one category could be compared: in_category( $single_category ). 241 * Prior to v2.7, this function could only be used in the WordPress Loop. 242 * As of 2.7, the function can be used anywhere if it is provided a post ID or post object. 243 * 244 * For more information on this and similar theme functions, check out 245 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 246 * Conditional Tags} article in the Theme Developer Handbook. 247 * 248 * @since 1.2.0 249 * @since 2.7.0 The `$post` parameter was added. 250 * 251 * @param int|string|int[]|string[] $category Category ID, name, slug, or array of such 252 * to check against. 253 * @param int|object $post Optional. Post to check instead of the current post. 254 * @return bool True if the current post is in any of the given categories. 255 */ 256 function in_category( $category, $post = null ) { 257 if ( empty( $category ) ) { 258 return false; 259 } 260 261 return has_category( $category, $post ); 262 } 263 264 /** 265 * Displays category list for a post in either HTML list or custom format. 266 * 267 * @since 0.71 268 * 269 * @param string $separator Optional. Separator between the categories. By default, the links are placed 270 * in an unordered list. An empty string will result in the default behavior. 271 * @param string $parents Optional. How to display the parents. 272 * @param int $post_id Optional. Post ID to retrieve categories. 273 */ 274 function the_category( $separator = '', $parents = '', $post_id = false ) { 275 echo get_the_category_list( $separator, $parents, $post_id ); 276 } 277 278 /** 279 * Retrieves category description. 280 * 281 * @since 1.0.0 282 * 283 * @param int $category Optional. Category ID. Defaults to the current category ID. 284 * @return string Category description, if available. 285 */ 286 function category_description( $category = 0 ) { 287 return term_description( $category ); 288 } 289 290 /** 291 * Displays or retrieves the HTML dropdown list of categories. 292 * 293 * The 'hierarchical' argument, which is disabled by default, will override the 294 * depth argument, unless it is true. When the argument is false, it will 295 * display all of the categories. When it is enabled it will use the value in 296 * the 'depth' argument. 297 * 298 * @since 2.1.0 299 * @since 4.2.0 Introduced the `value_field` argument. 300 * @since 4.6.0 Introduced the `required` argument. 301 * 302 * @param array|string $args { 303 * Optional. Array or string of arguments to generate a categories drop-down element. See WP_Term_Query::__construct() 304 * for information on additional accepted arguments. 305 * 306 * @type string $show_option_all Text to display for showing all categories. Default empty. 307 * @type string $show_option_none Text to display for showing no categories. Default empty. 308 * @type string $option_none_value Value to use when no category is selected. Default empty. 309 * @type string $orderby Which column to use for ordering categories. See get_terms() for a list 310 * of accepted values. Default 'id' (term_id). 311 * @type bool $pad_counts See get_terms() for an argument description. Default false. 312 * @type bool|int $show_count Whether to include post counts. Accepts 0, 1, or their bool equivalents. 313 * Default 0. 314 * @type bool|int $echo Whether to echo or return the generated markup. Accepts 0, 1, or their 315 * bool equivalents. Default 1. 316 * @type bool|int $hierarchical Whether to traverse the taxonomy hierarchy. Accepts 0, 1, or their bool 317 * equivalents. Default 0. 318 * @type int $depth Maximum depth. Default 0. 319 * @type int $tab_index Tab index for the select element. Default 0 (no tabindex). 320 * @type string $name Value for the 'name' attribute of the select element. Default 'cat'. 321 * @type string $id Value for the 'id' attribute of the select element. Defaults to the value 322 * of `$name`. 323 * @type string $class Value for the 'class' attribute of the select element. Default 'postform'. 324 * @type int|string $selected Value of the option that should be selected. Default 0. 325 * @type string $value_field Term field that should be used to populate the 'value' attribute 326 * of the option elements. Accepts any valid term field: 'term_id', 'name', 327 * 'slug', 'term_group', 'term_taxonomy_id', 'taxonomy', 'description', 328 * 'parent', 'count'. Default 'term_id'. 329 * @type string|array $taxonomy Name of the taxonomy or taxonomies to retrieve. Default 'category'. 330 * @type bool $hide_if_empty True to skip generating markup if no categories are found. 331 * Default false (create select element even if no categories are found). 332 * @type bool $required Whether the `<select>` element should have the HTML5 'required' attribute. 333 * Default false. 334 * @type Walker $walker Walker object to use to build the output. Default empty which results in a 335 * Walker_CategoryDropdown instance being used. 336 * } 337 * @return string HTML dropdown list of categories. 338 */ 339 function wp_dropdown_categories( $args = '' ) { 340 $defaults = array( 341 'show_option_all' => '', 342 'show_option_none' => '', 343 'orderby' => 'id', 344 'order' => 'ASC', 345 'show_count' => 0, 346 'hide_empty' => 1, 347 'child_of' => 0, 348 'exclude' => '', 349 'echo' => 1, 350 'selected' => 0, 351 'hierarchical' => 0, 352 'name' => 'cat', 353 'id' => '', 354 'class' => 'postform', 355 'depth' => 0, 356 'tab_index' => 0, 357 'taxonomy' => 'category', 358 'hide_if_empty' => false, 359 'option_none_value' => -1, 360 'value_field' => 'term_id', 361 'required' => false, 362 ); 363 364 $defaults['selected'] = ( is_category() ) ? get_query_var( 'cat' ) : 0; 365 366 // Back compat. 367 if ( isset( $args['type'] ) && 'link' === $args['type'] ) { 368 _deprecated_argument( 369 __FUNCTION__, 370 '3.0.0', 371 sprintf( 372 /* translators: 1: "type => link", 2: "taxonomy => link_category" */ 373 __( '%1$s is deprecated. Use %2$s instead.' ), 374 '<code>type => link</code>', 375 '<code>taxonomy => link_category</code>' 376 ) 377 ); 378 $args['taxonomy'] = 'link_category'; 379 } 380 381 // Parse incoming $args into an array and merge it with $defaults. 382 $parsed_args = wp_parse_args( $args, $defaults ); 383 384 $option_none_value = $parsed_args['option_none_value']; 385 386 if ( ! isset( $parsed_args['pad_counts'] ) && $parsed_args['show_count'] && $parsed_args['hierarchical'] ) { 387 $parsed_args['pad_counts'] = true; 388 } 389 390 $tab_index = $parsed_args['tab_index']; 391 392 $tab_index_attribute = ''; 393 if ( (int) $tab_index > 0 ) { 394 $tab_index_attribute = " tabindex=\"$tab_index\""; 395 } 396 397 // Avoid clashes with the 'name' param of get_terms(). 398 $get_terms_args = $parsed_args; 399 unset( $get_terms_args['name'] ); 400 $categories = get_terms( $get_terms_args ); 401 402 $name = esc_attr( $parsed_args['name'] ); 403 $class = esc_attr( $parsed_args['class'] ); 404 $id = $parsed_args['id'] ? esc_attr( $parsed_args['id'] ) : $name; 405 $required = $parsed_args['required'] ? 'required' : ''; 406 407 if ( ! $parsed_args['hide_if_empty'] || ! empty( $categories ) ) { 408 $output = "<select $required name='$name' id='$id' class='$class' $tab_index_attribute>\n"; 409 } else { 410 $output = ''; 411 } 412 if ( empty( $categories ) && ! $parsed_args['hide_if_empty'] && ! empty( $parsed_args['show_option_none'] ) ) { 413 414 /** 415 * Filters a taxonomy drop-down display element. 416 * 417 * A variety of taxonomy drop-down display elements can be modified 418 * just prior to display via this filter. Filterable arguments include 419 * 'show_option_none', 'show_option_all', and various forms of the 420 * term name. 421 * 422 * @since 1.2.0 423 * 424 * @see wp_dropdown_categories() 425 * 426 * @param string $element Category name. 427 * @param WP_Term|null $category The category object, or null if there's no corresponding category. 428 */ 429 $show_option_none = apply_filters( 'list_cats', $parsed_args['show_option_none'], null ); 430 $output .= "\t<option value='" . esc_attr( $option_none_value ) . "' selected='selected'>$show_option_none</option>\n"; 431 } 432 433 if ( ! empty( $categories ) ) { 434 435 if ( $parsed_args['show_option_all'] ) { 436 437 /** This filter is documented in wp-includes/category-template.php */ 438 $show_option_all = apply_filters( 'list_cats', $parsed_args['show_option_all'], null ); 439 $selected = ( '0' === (string) $parsed_args['selected'] ) ? " selected='selected'" : ''; 440 $output .= "\t<option value='0'$selected>$show_option_all</option>\n"; 441 } 442 443 if ( $parsed_args['show_option_none'] ) { 444 445 /** This filter is documented in wp-includes/category-template.php */ 446 $show_option_none = apply_filters( 'list_cats', $parsed_args['show_option_none'], null ); 447 $selected = selected( $option_none_value, $parsed_args['selected'], false ); 448 $output .= "\t<option value='" . esc_attr( $option_none_value ) . "'$selected>$show_option_none</option>\n"; 449 } 450 451 if ( $parsed_args['hierarchical'] ) { 452 $depth = $parsed_args['depth']; // Walk the full depth. 453 } else { 454 $depth = -1; // Flat. 455 } 456 $output .= walk_category_dropdown_tree( $categories, $depth, $parsed_args ); 457 } 458 459 if ( ! $parsed_args['hide_if_empty'] || ! empty( $categories ) ) { 460 $output .= "</select>\n"; 461 } 462 463 /** 464 * Filters the taxonomy drop-down output. 465 * 466 * @since 2.1.0 467 * 468 * @param string $output HTML output. 469 * @param array $parsed_args Arguments used to build the drop-down. 470 */ 471 $output = apply_filters( 'wp_dropdown_cats', $output, $parsed_args ); 472 473 if ( $parsed_args['echo'] ) { 474 echo $output; 475 } 476 477 return $output; 478 } 479 480 /** 481 * Displays or retrieves the HTML list of categories. 482 * 483 * @since 2.1.0 484 * @since 4.4.0 Introduced the `hide_title_if_empty` and `separator` arguments. 485 * @since 4.4.0 The `current_category` argument was modified to optionally accept an array of values. 486 * 487 * @param array|string $args { 488 * Array of optional arguments. See get_categories(), get_terms(), and WP_Term_Query::__construct() 489 * for information on additional accepted arguments. 490 * 491 * @type int|int[] $current_category ID of category, or array of IDs of categories, that should get the 492 * 'current-cat' class. Default 0. 493 * @type int $depth Category depth. Used for tab indentation. Default 0. 494 * @type bool|int $echo Whether to echo or return the generated markup. Accepts 0, 1, or their 495 * bool equivalents. Default 1. 496 * @type int[]|string $exclude Array or comma/space-separated string of term IDs to exclude. 497 * If `$hierarchical` is true, descendants of `$exclude` terms will also 498 * be excluded; see `$exclude_tree`. See get_terms(). 499 * Default empty string. 500 * @type int[]|string $exclude_tree Array or comma/space-separated string of term IDs to exclude, along 501 * with their descendants. See get_terms(). Default empty string. 502 * @type string $feed Text to use for the feed link. Default 'Feed for all posts filed 503 * under [cat name]'. 504 * @type string $feed_image URL of an image to use for the feed link. Default empty string. 505 * @type string $feed_type Feed type. Used to build feed link. See get_term_feed_link(). 506 * Default empty string (default feed). 507 * @type bool $hide_title_if_empty Whether to hide the `$title_li` element if there are no terms in 508 * the list. Default false (title will always be shown). 509 * @type string $separator Separator between links. Default '<br />'. 510 * @type bool|int $show_count Whether to include post counts. Accepts 0, 1, or their bool equivalents. 511 * Default 0. 512 * @type string $show_option_all Text to display for showing all categories. Default empty string. 513 * @type string $show_option_none Text to display for the 'no categories' option. 514 * Default 'No categories'. 515 * @type string $style The style used to display the categories list. If 'list', categories 516 * will be output as an unordered list. If left empty or another value, 517 * categories will be output separated by `<br>` tags. Default 'list'. 518 * @type string $taxonomy Name of the taxonomy to retrieve. Default 'category'. 519 * @type string $title_li Text to use for the list title `<li>` element. Pass an empty string 520 * to disable. Default 'Categories'. 521 * @type bool|int $use_desc_for_title Whether to use the category description as the title attribute. 522 * Accepts 0, 1, or their bool equivalents. Default 1. 523 * @type Walker $walker Walker object to use to build the output. Default empty which results 524 * in a Walker_Category instance being used. 525 * } 526 * @return void|string|false Void if 'echo' argument is true, HTML list of categories if 'echo' is false. 527 * False if the taxonomy does not exist. 528 */ 529 function wp_list_categories( $args = '' ) { 530 $defaults = array( 531 'child_of' => 0, 532 'current_category' => 0, 533 'depth' => 0, 534 'echo' => 1, 535 'exclude' => '', 536 'exclude_tree' => '', 537 'feed' => '', 538 'feed_image' => '', 539 'feed_type' => '', 540 'hide_empty' => 1, 541 'hide_title_if_empty' => false, 542 'hierarchical' => true, 543 'order' => 'ASC', 544 'orderby' => 'name', 545 'separator' => '<br />', 546 'show_count' => 0, 547 'show_option_all' => '', 548 'show_option_none' => __( 'No categories' ), 549 'style' => 'list', 550 'taxonomy' => 'category', 551 'title_li' => __( 'Categories' ), 552 'use_desc_for_title' => 1, 553 ); 554 555 $parsed_args = wp_parse_args( $args, $defaults ); 556 557 if ( ! isset( $parsed_args['pad_counts'] ) && $parsed_args['show_count'] && $parsed_args['hierarchical'] ) { 558 $parsed_args['pad_counts'] = true; 559 } 560 561 // Descendants of exclusions should be excluded too. 562 if ( true == $parsed_args['hierarchical'] ) { 563 $exclude_tree = array(); 564 565 if ( $parsed_args['exclude_tree'] ) { 566 $exclude_tree = array_merge( $exclude_tree, wp_parse_id_list( $parsed_args['exclude_tree'] ) ); 567 } 568 569 if ( $parsed_args['exclude'] ) { 570 $exclude_tree = array_merge( $exclude_tree, wp_parse_id_list( $parsed_args['exclude'] ) ); 571 } 572 573 $parsed_args['exclude_tree'] = $exclude_tree; 574 $parsed_args['exclude'] = ''; 575 } 576 577 if ( ! isset( $parsed_args['class'] ) ) { 578 $parsed_args['class'] = ( 'category' === $parsed_args['taxonomy'] ) ? 'categories' : $parsed_args['taxonomy']; 579 } 580 581 if ( ! taxonomy_exists( $parsed_args['taxonomy'] ) ) { 582 return false; 583 } 584 585 $show_option_all = $parsed_args['show_option_all']; 586 $show_option_none = $parsed_args['show_option_none']; 587 588 $categories = get_categories( $parsed_args ); 589 590 $output = ''; 591 592 if ( $parsed_args['title_li'] && 'list' === $parsed_args['style'] 593 && ( ! empty( $categories ) || ! $parsed_args['hide_title_if_empty'] ) 594 ) { 595 $output = '<li class="' . esc_attr( $parsed_args['class'] ) . '">' . $parsed_args['title_li'] . '<ul>'; 596 } 597 598 if ( empty( $categories ) ) { 599 if ( ! empty( $show_option_none ) ) { 600 if ( 'list' === $parsed_args['style'] ) { 601 $output .= '<li class="cat-item-none">' . $show_option_none . '</li>'; 602 } else { 603 $output .= $show_option_none; 604 } 605 } 606 } else { 607 if ( ! empty( $show_option_all ) ) { 608 609 $posts_page = ''; 610 611 // For taxonomies that belong only to custom post types, point to a valid archive. 612 $taxonomy_object = get_taxonomy( $parsed_args['taxonomy'] ); 613 if ( ! in_array( 'post', $taxonomy_object->object_type, true ) && ! in_array( 'page', $taxonomy_object->object_type, true ) ) { 614 foreach ( $taxonomy_object->object_type as $object_type ) { 615 $_object_type = get_post_type_object( $object_type ); 616 617 // Grab the first one. 618 if ( ! empty( $_object_type->has_archive ) ) { 619 $posts_page = get_post_type_archive_link( $object_type ); 620 break; 621 } 622 } 623 } 624 625 // Fallback for the 'All' link is the posts page. 626 if ( ! $posts_page ) { 627 if ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) ) { 628 $posts_page = get_permalink( get_option( 'page_for_posts' ) ); 629 } else { 630 $posts_page = home_url( '/' ); 631 } 632 } 633 634 $posts_page = esc_url( $posts_page ); 635 if ( 'list' === $parsed_args['style'] ) { 636 $output .= "<li class='cat-item-all'><a href='$posts_page'>$show_option_all</a></li>"; 637 } else { 638 $output .= "<a href='$posts_page'>$show_option_all</a>"; 639 } 640 } 641 642 if ( empty( $parsed_args['current_category'] ) && ( is_category() || is_tax() || is_tag() ) ) { 643 $current_term_object = get_queried_object(); 644 if ( $current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy ) { 645 $parsed_args['current_category'] = get_queried_object_id(); 646 } 647 } 648 649 if ( $parsed_args['hierarchical'] ) { 650 $depth = $parsed_args['depth']; 651 } else { 652 $depth = -1; // Flat. 653 } 654 $output .= walk_category_tree( $categories, $depth, $parsed_args ); 655 } 656 657 if ( $parsed_args['title_li'] && 'list' === $parsed_args['style'] 658 && ( ! empty( $categories ) || ! $parsed_args['hide_title_if_empty'] ) 659 ) { 660 $output .= '</ul></li>'; 661 } 662 663 /** 664 * Filters the HTML output of a taxonomy list. 665 * 666 * @since 2.1.0 667 * 668 * @param string $output HTML output. 669 * @param array|string $args An array or query string of taxonomy-listing arguments. See 670 * wp_list_categories() for information on accepted arguments. 671 */ 672 $html = apply_filters( 'wp_list_categories', $output, $args ); 673 674 if ( $parsed_args['echo'] ) { 675 echo $html; 676 } else { 677 return $html; 678 } 679 } 680 681 /** 682 * Displays a tag cloud. 683 * 684 * Outputs a list of tags in what is called a 'tag cloud', where the size of each tag 685 * is determined by how many times that particular tag has been assigned to posts. 686 * 687 * @since 2.3.0 688 * @since 2.8.0 Added the `taxonomy` argument. 689 * @since 4.8.0 Added the `show_count` argument. 690 * 691 * @param array|string $args { 692 * Optional. Array or string of arguments for displaying a tag cloud. See wp_generate_tag_cloud() 693 * and get_terms() for the full lists of arguments that can be passed in `$args`. 694 * 695 * @type int $number The number of tags to display. Accepts any positive integer 696 * or zero to return all. Default 45. 697 * @type string $link Whether to display term editing links or term permalinks. 698 * Accepts 'edit' and 'view'. Default 'view'. 699 * @type string $post_type The post type. Used to highlight the proper post type menu 700 * on the linked edit page. Defaults to the first post type 701 * associated with the taxonomy. 702 * @type bool $echo Whether or not to echo the return value. Default true. 703 * } 704 * @return void|string|string[] Void if 'echo' argument is true, or on failure. Otherwise, tag cloud 705 * as a string or an array, depending on 'format' argument. 706 */ 707 function wp_tag_cloud( $args = '' ) { 708 $defaults = array( 709 'smallest' => 8, 710 'largest' => 22, 711 'unit' => 'pt', 712 'number' => 45, 713 'format' => 'flat', 714 'separator' => "\n", 715 'orderby' => 'name', 716 'order' => 'ASC', 717 'exclude' => '', 718 'include' => '', 719 'link' => 'view', 720 'taxonomy' => 'post_tag', 721 'post_type' => '', 722 'echo' => true, 723 'show_count' => 0, 724 ); 725 726 $args = wp_parse_args( $args, $defaults ); 727 728 $tags = get_terms( 729 array_merge( 730 $args, 731 array( 732 'orderby' => 'count', 733 'order' => 'DESC', 734 ) 735 ) 736 ); // Always query top tags. 737 738 if ( empty( $tags ) || is_wp_error( $tags ) ) { 739 return; 740 } 741 742 foreach ( $tags as $key => $tag ) { 743 if ( 'edit' === $args['link'] ) { 744 $link = get_edit_term_link( $tag, $tag->taxonomy, $args['post_type'] ); 745 } else { 746 $link = get_term_link( $tag, $tag->taxonomy ); 747 } 748 749 if ( is_wp_error( $link ) ) { 750 return; 751 } 752 753 $tags[ $key ]->link = $link; 754 $tags[ $key ]->id = $tag->term_id; 755 } 756 757 // Here's where those top tags get sorted according to $args. 758 $return = wp_generate_tag_cloud( $tags, $args ); 759 760 /** 761 * Filters the tag cloud output. 762 * 763 * @since 2.3.0 764 * 765 * @param string|string[] $return Tag cloud as a string or an array, depending on 'format' argument. 766 * @param array $args An array of tag cloud arguments. See wp_tag_cloud() 767 * for information on accepted arguments. 768 */ 769 $return = apply_filters( 'wp_tag_cloud', $return, $args ); 770 771 if ( 'array' === $args['format'] || empty( $args['echo'] ) ) { 772 return $return; 773 } 774 775 echo $return; 776 } 777 778 /** 779 * Default topic count scaling for tag links. 780 * 781 * @since 2.9.0 782 * 783 * @param int $count Number of posts with that tag. 784 * @return int Scaled count. 785 */ 786 function default_topic_count_scale( $count ) { 787 return round( log10( $count + 1 ) * 100 ); 788 } 789 790 /** 791 * Generates a tag cloud (heatmap) from provided data. 792 * 793 * @todo Complete functionality. 794 * @since 2.3.0 795 * @since 4.8.0 Added the `show_count` argument. 796 * 797 * @param WP_Term[] $tags Array of WP_Term objects to generate the tag cloud for. 798 * @param string|array $args { 799 * Optional. Array or string of arguments for generating a tag cloud. 800 * 801 * @type int $smallest Smallest font size used to display tags. Paired 802 * with the value of `$unit`, to determine CSS text 803 * size unit. Default 8 (pt). 804 * @type int $largest Largest font size used to display tags. Paired 805 * with the value of `$unit`, to determine CSS text 806 * size unit. Default 22 (pt). 807 * @type string $unit CSS text size unit to use with the `$smallest` 808 * and `$largest` values. Accepts any valid CSS text 809 * size unit. Default 'pt'. 810 * @type int $number The number of tags to return. Accepts any 811 * positive integer or zero to return all. 812 * Default 0. 813 * @type string $format Format to display the tag cloud in. Accepts 'flat' 814 * (tags separated with spaces), 'list' (tags displayed 815 * in an unordered list), or 'array' (returns an array). 816 * Default 'flat'. 817 * @type string $separator HTML or text to separate the tags. Default "\n" (newline). 818 * @type string $orderby Value to order tags by. Accepts 'name' or 'count'. 819 * Default 'name'. The {@see 'tag_cloud_sort'} filter 820 * can also affect how tags are sorted. 821 * @type string $order How to order the tags. Accepts 'ASC' (ascending), 822 * 'DESC' (descending), or 'RAND' (random). Default 'ASC'. 823 * @type int|bool $filter Whether to enable filtering of the final output 824 * via {@see 'wp_generate_tag_cloud'}. Default 1. 825 * @type string $topic_count_text Nooped plural text from _n_noop() to supply to 826 * tag counts. Default null. 827 * @type callable $topic_count_text_callback Callback used to generate nooped plural text for 828 * tag counts based on the count. Default null. 829 * @type callable $topic_count_scale_callback Callback used to determine the tag count scaling 830 * value. Default default_topic_count_scale(). 831 * @type bool|int $show_count Whether to display the tag counts. Default 0. Accepts 832 * 0, 1, or their bool equivalents. 833 * } 834 * @return string|string[] Tag cloud as a string or an array, depending on 'format' argument. 835 */ 836 function wp_generate_tag_cloud( $tags, $args = '' ) { 837 $defaults = array( 838 'smallest' => 8, 839 'largest' => 22, 840 'unit' => 'pt', 841 'number' => 0, 842 'format' => 'flat', 843 'separator' => "\n", 844 'orderby' => 'name', 845 'order' => 'ASC', 846 'topic_count_text' => null, 847 'topic_count_text_callback' => null, 848 'topic_count_scale_callback' => 'default_topic_count_scale', 849 'filter' => 1, 850 'show_count' => 0, 851 ); 852 853 $args = wp_parse_args( $args, $defaults ); 854 855 $return = ( 'array' === $args['format'] ) ? array() : ''; 856 857 if ( empty( $tags ) ) { 858 return $return; 859 } 860 861 // Juggle topic counts. 862 if ( isset( $args['topic_count_text'] ) ) { 863 // First look for nooped plural support via topic_count_text. 864 $translate_nooped_plural = $args['topic_count_text']; 865 } elseif ( ! empty( $args['topic_count_text_callback'] ) ) { 866 // Look for the alternative callback style. Ignore the previous default. 867 if ( 'default_topic_count_text' === $args['topic_count_text_callback'] ) { 868 /* translators: %s: Number of items (tags). */ 869 $translate_nooped_plural = _n_noop( '%s item', '%s items' ); 870 } else { 871 $translate_nooped_plural = false; 872 } 873 } elseif ( isset( $args['single_text'] ) && isset( $args['multiple_text'] ) ) { 874 // If no callback exists, look for the old-style single_text and multiple_text arguments. 875 // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralSingle,WordPress.WP.I18n.NonSingularStringLiteralPlural 876 $translate_nooped_plural = _n_noop( $args['single_text'], $args['multiple_text'] ); 877 } else { 878 // This is the default for when no callback, plural, or argument is passed in. 879 /* translators: %s: Number of items (tags). */ 880 $translate_nooped_plural = _n_noop( '%s item', '%s items' ); 881 } 882 883 /** 884 * Filters how the items in a tag cloud are sorted. 885 * 886 * @since 2.8.0 887 * 888 * @param WP_Term[] $tags Ordered array of terms. 889 * @param array $args An array of tag cloud arguments. 890 */ 891 $tags_sorted = apply_filters( 'tag_cloud_sort', $tags, $args ); 892 if ( empty( $tags_sorted ) ) { 893 return $return; 894 } 895 896 if ( $tags_sorted !== $tags ) { 897 $tags = $tags_sorted; 898 unset( $tags_sorted ); 899 } else { 900 if ( 'RAND' === $args['order'] ) { 901 shuffle( $tags ); 902 } else { 903 // SQL cannot save you; this is a second (potentially different) sort on a subset of data. 904 if ( 'name' === $args['orderby'] ) { 905 uasort( $tags, '_wp_object_name_sort_cb' ); 906 } else { 907 uasort( $tags, '_wp_object_count_sort_cb' ); 908 } 909 910 if ( 'DESC' === $args['order'] ) { 911 $tags = array_reverse( $tags, true ); 912 } 913 } 914 } 915 916 if ( $args['number'] > 0 ) { 917 $tags = array_slice( $tags, 0, $args['number'] ); 918 } 919 920 $counts = array(); 921 $real_counts = array(); // For the alt tag. 922 foreach ( (array) $tags as $key => $tag ) { 923 $real_counts[ $key ] = $tag->count; 924 $counts[ $key ] = call_user_func( $args['topic_count_scale_callback'], $tag->count ); 925 } 926 927 $min_count = min( $counts ); 928 $spread = max( $counts ) - $min_count; 929 if ( $spread <= 0 ) { 930 $spread = 1; 931 } 932 $font_spread = $args['largest'] - $args['smallest']; 933 if ( $font_spread < 0 ) { 934 $font_spread = 1; 935 } 936 $font_step = $font_spread / $spread; 937 938 $aria_label = false; 939 /* 940 * Determine whether to output an 'aria-label' attribute with the tag name and count. 941 * When tags have a different font size, they visually convey an important information 942 * that should be available to assistive technologies too. On the other hand, sometimes 943 * themes set up the Tag Cloud to display all tags with the same font size (setting 944 * the 'smallest' and 'largest' arguments to the same value). 945 * In order to always serve the same content to all users, the 'aria-label' gets printed out: 946 * - when tags have a different size 947 * - when the tag count is displayed (for example when users check the checkbox in the 948 * Tag Cloud widget), regardless of the tags font size 949 */ 950 if ( $args['show_count'] || 0 !== $font_spread ) { 951 $aria_label = true; 952 } 953 954 // Assemble the data that will be used to generate the tag cloud markup. 955 $tags_data = array(); 956 foreach ( $tags as $key => $tag ) { 957 $tag_id = isset( $tag->id ) ? $tag->id : $key; 958 959 $count = $counts[ $key ]; 960 $real_count = $real_counts[ $key ]; 961 962 if ( $translate_nooped_plural ) { 963 $formatted_count = sprintf( translate_nooped_plural( $translate_nooped_plural, $real_count ), number_format_i18n( $real_count ) ); 964 } else { 965 $formatted_count = call_user_func( $args['topic_count_text_callback'], $real_count, $tag, $args ); 966 } 967 968 $tags_data[] = array( 969 'id' => $tag_id, 970 'url' => ( '#' !== $tag->link ) ? $tag->link : '#', 971 'role' => ( '#' !== $tag->link ) ? '' : ' role="button"', 972 'name' => $tag->name, 973 'formatted_count' => $formatted_count, 974 'slug' => $tag->slug, 975 'real_count' => $real_count, 976 'class' => 'tag-cloud-link tag-link-' . $tag_id, 977 'font_size' => $args['smallest'] + ( $count - $min_count ) * $font_step, 978 'aria_label' => $aria_label ? sprintf( ' aria-label="%1$s (%2$s)"', esc_attr( $tag->name ), esc_attr( $formatted_count ) ) : '', 979 'show_count' => $args['show_count'] ? '<span class="tag-link-count"> (' . $real_count . ')</span>' : '', 980 ); 981 } 982 983 /** 984 * Filters the data used to generate the tag cloud. 985 * 986 * @since 4.3.0 987 * 988 * @param array[] $tags_data An array of term data arrays for terms used to generate the tag cloud. 989 */ 990 $tags_data = apply_filters( 'wp_generate_tag_cloud_data', $tags_data ); 991 992 $a = array(); 993 994 // Generate the output links array. 995 foreach ( $tags_data as $key => $tag_data ) { 996 $class = $tag_data['class'] . ' tag-link-position-' . ( $key + 1 ); 997 $a[] = sprintf( 998 '<a href="%1$s"%2$s class="%3$s" style="font-size: %4$s;"%5$s>%6$s%7$s</a>', 999 esc_url( $tag_data['url'] ), 1000 $tag_data['role'], 1001 esc_attr( $class ), 1002 esc_attr( str_replace( ',', '.', $tag_data['font_size'] ) . $args['unit'] ), 1003 $tag_data['aria_label'], 1004 esc_html( $tag_data['name'] ), 1005 $tag_data['show_count'] 1006 ); 1007 } 1008 1009 switch ( $args['format'] ) { 1010 case 'array': 1011 $return =& $a; 1012 break; 1013 case 'list': 1014 /* 1015 * Force role="list", as some browsers (sic: Safari 10) don't expose to assistive 1016 * technologies the default role when the list is styled with `list-style: none`. 1017 * Note: this is redundant but doesn't harm. 1018 */ 1019 $return = "<ul class='wp-tag-cloud' role='list'>\n\t<li>"; 1020 $return .= implode( "</li>\n\t<li>", $a ); 1021 $return .= "</li>\n</ul>\n"; 1022 break; 1023 default: 1024 $return = implode( $args['separator'], $a ); 1025 break; 1026 } 1027 1028 if ( $args['filter'] ) { 1029 /** 1030 * Filters the generated output of a tag cloud. 1031 * 1032 * The filter is only evaluated if a true value is passed 1033 * to the $filter argument in wp_generate_tag_cloud(). 1034 * 1035 * @since 2.3.0 1036 * 1037 * @see wp_generate_tag_cloud() 1038 * 1039 * @param string[]|string $return String containing the generated HTML tag cloud output 1040 * or an array of tag links if the 'format' argument 1041 * equals 'array'. 1042 * @param WP_Term[] $tags An array of terms used in the tag cloud. 1043 * @param array $args An array of wp_generate_tag_cloud() arguments. 1044 */ 1045 return apply_filters( 'wp_generate_tag_cloud', $return, $tags, $args ); 1046 } else { 1047 return $return; 1048 } 1049 } 1050 1051 /** 1052 * Serves as a callback for comparing objects based on name. 1053 * 1054 * Used with `uasort()`. 1055 * 1056 * @since 3.1.0 1057 * @access private 1058 * 1059 * @param object $a The first object to compare. 1060 * @param object $b The second object to compare. 1061 * @return int Negative number if `$a->name` is less than `$b->name`, zero if they are equal, 1062 * or greater than zero if `$a->name` is greater than `$b->name`. 1063 */ 1064 function _wp_object_name_sort_cb( $a, $b ) { 1065 return strnatcasecmp( $a->name, $b->name ); 1066 } 1067 1068 /** 1069 * Serves as a callback for comparing objects based on count. 1070 * 1071 * Used with `uasort()`. 1072 * 1073 * @since 3.1.0 1074 * @access private 1075 * 1076 * @param object $a The first object to compare. 1077 * @param object $b The second object to compare. 1078 * @return bool Whether the count value for `$a` is greater than the count value for `$b`. 1079 */ 1080 function _wp_object_count_sort_cb( $a, $b ) { 1081 return ( $a->count > $b->count ); 1082 } 1083 1084 // 1085 // Helper functions. 1086 // 1087 1088 /** 1089 * Retrieves HTML list content for category list. 1090 * 1091 * @since 2.1.0 1092 * @since 5.3.0 Formalized the existing `...$args` parameter by adding it 1093 * to the function signature. 1094 * 1095 * @uses Walker_Category to create HTML list content. 1096 * @see Walker::walk() for parameters and return description. 1097 * 1098 * @param mixed ...$args Elements array, maximum hierarchical depth and optional additional arguments. 1099 * @return string 1100 */ 1101 function walk_category_tree( ...$args ) { 1102 // The user's options are the third parameter. 1103 if ( empty( $args[2]['walker'] ) || ! ( $args[2]['walker'] instanceof Walker ) ) { 1104 $walker = new Walker_Category; 1105 } else { 1106 /** 1107 * @var Walker $walker 1108 */ 1109 $walker = $args[2]['walker']; 1110 } 1111 return $walker->walk( ...$args ); 1112 } 1113 1114 /** 1115 * Retrieves HTML dropdown (select) content for category list. 1116 * 1117 * @since 2.1.0 1118 * @since 5.3.0 Formalized the existing `...$args` parameter by adding it 1119 * to the function signature. 1120 * 1121 * @uses Walker_CategoryDropdown to create HTML dropdown content. 1122 * @see Walker::walk() for parameters and return description. 1123 * 1124 * @param mixed ...$args Elements array, maximum hierarchical depth and optional additional arguments. 1125 * @return string 1126 */ 1127 function walk_category_dropdown_tree( ...$args ) { 1128 // The user's options are the third parameter. 1129 if ( empty( $args[2]['walker'] ) || ! ( $args[2]['walker'] instanceof Walker ) ) { 1130 $walker = new Walker_CategoryDropdown; 1131 } else { 1132 /** 1133 * @var Walker $walker 1134 */ 1135 $walker = $args[2]['walker']; 1136 } 1137 return $walker->walk( ...$args ); 1138 } 1139 1140 // 1141 // Tags. 1142 // 1143 1144 /** 1145 * Retrieves the link to the tag. 1146 * 1147 * @since 2.3.0 1148 * 1149 * @see get_term_link() 1150 * 1151 * @param int|object $tag Tag ID or object. 1152 * @return string Link on success, empty string if tag does not exist. 1153 */ 1154 function get_tag_link( $tag ) { 1155 return get_category_link( $tag ); 1156 } 1157 1158 /** 1159 * Retrieves the tags for a post. 1160 * 1161 * @since 2.3.0 1162 * 1163 * @param int|WP_Post $post_id Post ID or object. 1164 * @return WP_Term[]|false|WP_Error Array of WP_Term objects on success, false if there are no terms 1165 * or the post does not exist, WP_Error on failure. 1166 */ 1167 function get_the_tags( $post_id = 0 ) { 1168 $terms = get_the_terms( $post_id, 'post_tag' ); 1169 1170 /** 1171 * Filters the array of tags for the given post. 1172 * 1173 * @since 2.3.0 1174 * 1175 * @see get_the_terms() 1176 * 1177 * @param WP_Term[]|false|WP_Error $terms Array of WP_Term objects on success, false if there are no terms 1178 * or the post does not exist, WP_Error on failure. 1179 */ 1180 return apply_filters( 'get_the_tags', $terms ); 1181 } 1182 1183 /** 1184 * Retrieves the tags for a post formatted as a string. 1185 * 1186 * @since 2.3.0 1187 * 1188 * @param string $before Optional. String to use before the tags. Default empty. 1189 * @param string $sep Optional. String to use between the tags. Default empty. 1190 * @param string $after Optional. String to use after the tags. Default empty. 1191 * @param int $post_id Optional. Post ID. Defaults to the current post ID. 1192 * @return string|false|WP_Error A list of tags on success, false if there are no terms, 1193 * WP_Error on failure. 1194 */ 1195 function get_the_tag_list( $before = '', $sep = '', $after = '', $post_id = 0 ) { 1196 $tag_list = get_the_term_list( $post_id, 'post_tag', $before, $sep, $after ); 1197 1198 /** 1199 * Filters the tags list for a given post. 1200 * 1201 * @since 2.3.0 1202 * 1203 * @param string $tag_list List of tags. 1204 * @param string $before String to use before the tags. 1205 * @param string $sep String to use between the tags. 1206 * @param string $after String to use after the tags. 1207 * @param int $post_id Post ID. 1208 */ 1209 return apply_filters( 'the_tags', $tag_list, $before, $sep, $after, $post_id ); 1210 } 1211 1212 /** 1213 * Displays the tags for a post. 1214 * 1215 * @since 2.3.0 1216 * 1217 * @param string $before Optional. String to use before the tags. Defaults to 'Tags:'. 1218 * @param string $sep Optional. String to use between the tags. Default ', '. 1219 * @param string $after Optional. String to use after the tags. Default empty. 1220 */ 1221 function the_tags( $before = null, $sep = ', ', $after = '' ) { 1222 if ( null === $before ) { 1223 $before = __( 'Tags: ' ); 1224 } 1225 1226 $the_tags = get_the_tag_list( $before, $sep, $after ); 1227 1228 if ( ! is_wp_error( $the_tags ) ) { 1229 echo $the_tags; 1230 } 1231 } 1232 1233 /** 1234 * Retrieves tag description. 1235 * 1236 * @since 2.8.0 1237 * 1238 * @param int $tag Optional. Tag ID. Defaults to the current tag ID. 1239 * @return string Tag description, if available. 1240 */ 1241 function tag_description( $tag = 0 ) { 1242 return term_description( $tag ); 1243 } 1244 1245 /** 1246 * Retrieves term description. 1247 * 1248 * @since 2.8.0 1249 * @since 4.9.2 The `$taxonomy` parameter was deprecated. 1250 * 1251 * @param int $term Optional. Term ID. Defaults to the current term ID. 1252 * @param null $deprecated Deprecated. Not used. 1253 * @return string Term description, if available. 1254 */ 1255 function term_description( $term = 0, $deprecated = null ) { 1256 if ( ! $term && ( is_tax() || is_tag() || is_category() ) ) { 1257 $term = get_queried_object(); 1258 if ( $term ) { 1259 $term = $term->term_id; 1260 } 1261 } 1262 1263 $description = get_term_field( 'description', $term ); 1264 1265 return is_wp_error( $description ) ? '' : $description; 1266 } 1267 1268 /** 1269 * Retrieves the terms of the taxonomy that are attached to the post. 1270 * 1271 * @since 2.5.0 1272 * 1273 * @param int|WP_Post $post Post ID or object. 1274 * @param string $taxonomy Taxonomy name. 1275 * @return WP_Term[]|false|WP_Error Array of WP_Term objects on success, false if there are no terms 1276 * or the post does not exist, WP_Error on failure. 1277 */ 1278 function get_the_terms( $post, $taxonomy ) { 1279 $post = get_post( $post ); 1280 if ( ! $post ) { 1281 return false; 1282 } 1283 1284 $terms = get_object_term_cache( $post->ID, $taxonomy ); 1285 if ( false === $terms ) { 1286 $terms = wp_get_object_terms( $post->ID, $taxonomy ); 1287 if ( ! is_wp_error( $terms ) ) { 1288 $term_ids = wp_list_pluck( $terms, 'term_id' ); 1289 wp_cache_add( $post->ID, $term_ids, $taxonomy . '_relationships' ); 1290 } 1291 } 1292 1293 /** 1294 * Filters the list of terms attached to the given post. 1295 * 1296 * @since 3.1.0 1297 * 1298 * @param WP_Term[]|WP_Error $terms Array of attached terms, or WP_Error on failure. 1299 * @param int $post_id Post ID. 1300 * @param string $taxonomy Name of the taxonomy. 1301 */ 1302 $terms = apply_filters( 'get_the_terms', $terms, $post->ID, $taxonomy ); 1303 1304 if ( empty( $terms ) ) { 1305 return false; 1306 } 1307 1308 return $terms; 1309 } 1310 1311 /** 1312 * Retrieves a post's terms as a list with specified format. 1313 * 1314 * Terms are linked to their respective term listing pages. 1315 * 1316 * @since 2.5.0 1317 * 1318 * @param int $post_id Post ID. 1319 * @param string $taxonomy Taxonomy name. 1320 * @param string $before Optional. String to use before the terms. Default empty. 1321 * @param string $sep Optional. String to use between the terms. Default empty. 1322 * @param string $after Optional. String to use after the terms. Default empty. 1323 * @return string|false|WP_Error A list of terms on success, false if there are no terms, 1324 * WP_Error on failure. 1325 */ 1326 function get_the_term_list( $post_id, $taxonomy, $before = '', $sep = '', $after = '' ) { 1327 $terms = get_the_terms( $post_id, $taxonomy ); 1328 1329 if ( is_wp_error( $terms ) ) { 1330 return $terms; 1331 } 1332 1333 if ( empty( $terms ) ) { 1334 return false; 1335 } 1336 1337 $links = array(); 1338 1339 foreach ( $terms as $term ) { 1340 $link = get_term_link( $term, $taxonomy ); 1341 if ( is_wp_error( $link ) ) { 1342 return $link; 1343 } 1344 $links[] = '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a>'; 1345 } 1346 1347 /** 1348 * Filters the term links for a given taxonomy. 1349 * 1350 * The dynamic portion of the hook name, `$taxonomy`, refers 1351 * to the taxonomy slug. 1352 * 1353 * Possible hook names include: 1354 * 1355 * - `term_links-category` 1356 * - `term_links-post_tag` 1357 * - `term_links-post_format` 1358 * 1359 * @since 2.5.0 1360 * 1361 * @param string[] $links An array of term links. 1362 */ 1363 $term_links = apply_filters( "term_links-{$taxonomy}", $links ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores 1364 1365 return $before . implode( $sep, $term_links ) . $after; 1366 } 1367 1368 /** 1369 * Retrieves term parents with separator. 1370 * 1371 * @since 4.8.0 1372 * 1373 * @param int $term_id Term ID. 1374 * @param string $taxonomy Taxonomy name. 1375 * @param string|array $args { 1376 * Array of optional arguments. 1377 * 1378 * @type string $format Use term names or slugs for display. Accepts 'name' or 'slug'. 1379 * Default 'name'. 1380 * @type string $separator Separator for between the terms. Default '/'. 1381 * @type bool $link Whether to format as a link. Default true. 1382 * @type bool $inclusive Include the term to get the parents for. Default true. 1383 * } 1384 * @return string|WP_Error A list of term parents on success, WP_Error or empty string on failure. 1385 */ 1386 function get_term_parents_list( $term_id, $taxonomy, $args = array() ) { 1387 $list = ''; 1388 $term = get_term( $term_id, $taxonomy ); 1389 1390 if ( is_wp_error( $term ) ) { 1391 return $term; 1392 } 1393 1394 if ( ! $term ) { 1395 return $list; 1396 } 1397 1398 $term_id = $term->term_id; 1399 1400 $defaults = array( 1401 'format' => 'name', 1402 'separator' => '/', 1403 'link' => true, 1404 'inclusive' => true, 1405 ); 1406 1407 $args = wp_parse_args( $args, $defaults ); 1408 1409 foreach ( array( 'link', 'inclusive' ) as $bool ) { 1410 $args[ $bool ] = wp_validate_boolean( $args[ $bool ] ); 1411 } 1412 1413 $parents = get_ancestors( $term_id, $taxonomy, 'taxonomy' ); 1414 1415 if ( $args['inclusive'] ) { 1416 array_unshift( $parents, $term_id ); 1417 } 1418 1419 foreach ( array_reverse( $parents ) as $term_id ) { 1420 $parent = get_term( $term_id, $taxonomy ); 1421 $name = ( 'slug' === $args['format'] ) ? $parent->slug : $parent->name; 1422 1423 if ( $args['link'] ) { 1424 $list .= '<a href="' . esc_url( get_term_link( $parent->term_id, $taxonomy ) ) . '">' . $name . '</a>' . $args['separator']; 1425 } else { 1426 $list .= $name . $args['separator']; 1427 } 1428 } 1429 1430 return $list; 1431 } 1432 1433 /** 1434 * Displays the terms for a post in a list. 1435 * 1436 * @since 2.5.0 1437 * 1438 * @param int $post_id Post ID. 1439 * @param string $taxonomy Taxonomy name. 1440 * @param string $before Optional. String to use before the terms. Default empty. 1441 * @param string $sep Optional. String to use between the terms. Default ', '. 1442 * @param string $after Optional. String to use after the terms. Default empty. 1443 * @return void|false Void on success, false on failure. 1444 */ 1445 function the_terms( $post_id, $taxonomy, $before = '', $sep = ', ', $after = '' ) { 1446 $term_list = get_the_term_list( $post_id, $taxonomy, $before, $sep, $after ); 1447 1448 if ( is_wp_error( $term_list ) ) { 1449 return false; 1450 } 1451 1452 /** 1453 * Filters the list of terms to display. 1454 * 1455 * @since 2.9.0 1456 * 1457 * @param string $term_list List of terms to display. 1458 * @param string $taxonomy The taxonomy name. 1459 * @param string $before String to use before the terms. 1460 * @param string $sep String to use between the terms. 1461 * @param string $after String to use after the terms. 1462 */ 1463 echo apply_filters( 'the_terms', $term_list, $taxonomy, $before, $sep, $after ); 1464 } 1465 1466 /** 1467 * Checks if the current post has any of given category. 1468 * 1469 * The given categories are checked against the post's categories' term_ids, names and slugs. 1470 * Categories given as integers will only be checked against the post's categories' term_ids. 1471 * 1472 * If no categories are given, determines if post has any categories. 1473 * 1474 * @since 3.1.0 1475 * 1476 * @param string|int|array $category Optional. The category name/term_id/slug, 1477 * or an array of them to check for. Default empty. 1478 * @param int|object $post Optional. Post to check instead of the current post. 1479 * @return bool True if the current post has any of the given categories 1480 * (or any category, if no category specified). False otherwise. 1481 */ 1482 function has_category( $category = '', $post = null ) { 1483 return has_term( $category, 'category', $post ); 1484 } 1485 1486 /** 1487 * Checks if the current post has any of given tags. 1488 * 1489 * The given tags are checked against the post's tags' term_ids, names and slugs. 1490 * Tags given as integers will only be checked against the post's tags' term_ids. 1491 * 1492 * If no tags are given, determines if post has any tags. 1493 * 1494 * For more information on this and similar theme functions, check out 1495 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 1496 * Conditional Tags} article in the Theme Developer Handbook. 1497 * 1498 * @since 2.6.0 1499 * @since 2.7.0 Tags given as integers are only checked against 1500 * the post's tags' term_ids, not names or slugs. 1501 * @since 2.7.0 Can be used outside of the WordPress Loop if `$post` is provided. 1502 * 1503 * @param string|int|array $tag Optional. The tag name/term_id/slug, 1504 * or an array of them to check for. Default empty. 1505 * @param int|object $post Optional. Post to check instead of the current post. 1506 * @return bool True if the current post has any of the given tags 1507 * (or any tag, if no tag specified). False otherwise. 1508 */ 1509 function has_tag( $tag = '', $post = null ) { 1510 return has_term( $tag, 'post_tag', $post ); 1511 } 1512 1513 /** 1514 * Checks if the current post has any of given terms. 1515 * 1516 * The given terms are checked against the post's terms' term_ids, names and slugs. 1517 * Terms given as integers will only be checked against the post's terms' term_ids. 1518 * 1519 * If no terms are given, determines if post has any terms. 1520 * 1521 * @since 3.1.0 1522 * 1523 * @param string|int|array $term Optional. The term name/term_id/slug, 1524 * or an array of them to check for. Default empty. 1525 * @param string $taxonomy Optional. Taxonomy name. Default empty. 1526 * @param int|WP_Post $post Optional. Post to check instead of the current post. 1527 * @return bool True if the current post has any of the given terms 1528 * (or any term, if no term specified). False otherwise. 1529 */ 1530 function has_term( $term = '', $taxonomy = '', $post = null ) { 1531 $post = get_post( $post ); 1532 1533 if ( ! $post ) { 1534 return false; 1535 } 1536 1537 $r = is_object_in_term( $post->ID, $taxonomy, $term ); 1538 if ( is_wp_error( $r ) ) { 1539 return false; 1540 } 1541 1542 return $r; 1543 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:03 2024 | Cross-referenced by PHPXref 0.7.1 |