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