Changeset 34110
- Timestamp:
- 09/14/2015 03:09:37 AM (9 years ago)
- Location:
- trunk/src/wp-includes
- Files:
-
- 2 edited
- 3 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/category-template.php
r33804 r34110 973 973 } 974 974 975 /**976 * Create HTML list of categories.977 *978 * @package WordPress979 * @since 2.1.0980 * @uses Walker981 */982 class Walker_Category extends Walker {983 /**984 * What the class handles.985 *986 * @see Walker::$tree_type987 * @since 2.1.0988 * @var string989 */990 public $tree_type = 'category';991 992 /**993 * Database fields to use.994 *995 * @see Walker::$db_fields996 * @since 2.1.0997 * @todo Decouple this998 * @var array999 */1000 public $db_fields = array ('parent' => 'parent', 'id' => 'term_id');1001 1002 /**1003 * Starts the list before the elements are added.1004 *1005 * @see Walker::start_lvl()1006 *1007 * @since 2.1.01008 *1009 * @param string $output Passed by reference. Used to append additional content.1010 * @param int $depth Depth of category. Used for tab indentation.1011 * @param array $args An array of arguments. Will only append content if style argument value is 'list'.1012 * @see wp_list_categories()1013 */1014 public function start_lvl( &$output, $depth = 0, $args = array() ) {1015 if ( 'list' != $args['style'] )1016 return;1017 1018 $indent = str_repeat("\t", $depth);1019 $output .= "$indent<ul class='children'>\n";1020 }1021 1022 /**1023 * Ends the list of after the elements are added.1024 *1025 * @see Walker::end_lvl()1026 *1027 * @since 2.1.01028 *1029 * @param string $output Passed by reference. Used to append additional content.1030 * @param int $depth Depth of category. Used for tab indentation.1031 * @param array $args An array of arguments. Will only append content if style argument value is 'list'.1032 * @wsee wp_list_categories()1033 */1034 public function end_lvl( &$output, $depth = 0, $args = array() ) {1035 if ( 'list' != $args['style'] )1036 return;1037 1038 $indent = str_repeat("\t", $depth);1039 $output .= "$indent</ul>\n";1040 }1041 1042 /**1043 * Start the element output.1044 *1045 * @see Walker::start_el()1046 *1047 * @since 2.1.01048 *1049 * @param string $output Passed by reference. Used to append additional content.1050 * @param object $category Category data object.1051 * @param int $depth Depth of category in reference to parents. Default 0.1052 * @param array $args An array of arguments. @see wp_list_categories()1053 * @param int $id ID of the current category.1054 */1055 public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {1056 /** This filter is documented in wp-includes/category-template.php */1057 $cat_name = apply_filters(1058 'list_cats',1059 esc_attr( $category->name ),1060 $category1061 );1062 1063 // Don't generate an element if the category name is empty.1064 if ( ! $cat_name ) {1065 return;1066 }1067 1068 $link = '<a href="' . esc_url( get_term_link( $category ) ) . '" ';1069 if ( $args['use_desc_for_title'] && ! empty( $category->description ) ) {1070 /**1071 * Filter the category description for display.1072 *1073 * @since 1.2.01074 *1075 * @param string $description Category description.1076 * @param object $category Category object.1077 */1078 $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';1079 }1080 1081 $link .= '>';1082 $link .= $cat_name . '</a>';1083 1084 if ( ! empty( $args['feed_image'] ) || ! empty( $args['feed'] ) ) {1085 $link .= ' ';1086 1087 if ( empty( $args['feed_image'] ) ) {1088 $link .= '(';1089 }1090 1091 $link .= '<a href="' . esc_url( get_term_feed_link( $category->term_id, $category->taxonomy, $args['feed_type'] ) ) . '"';1092 1093 if ( empty( $args['feed'] ) ) {1094 $alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';1095 } else {1096 $alt = ' alt="' . $args['feed'] . '"';1097 $name = $args['feed'];1098 $link .= empty( $args['title'] ) ? '' : $args['title'];1099 }1100 1101 $link .= '>';1102 1103 if ( empty( $args['feed_image'] ) ) {1104 $link .= $name;1105 } else {1106 $link .= "<img src='" . $args['feed_image'] . "'$alt" . ' />';1107 }1108 $link .= '</a>';1109 1110 if ( empty( $args['feed_image'] ) ) {1111 $link .= ')';1112 }1113 }1114 1115 if ( ! empty( $args['show_count'] ) ) {1116 $link .= ' (' . number_format_i18n( $category->count ) . ')';1117 }1118 if ( 'list' == $args['style'] ) {1119 $output .= "\t<li";1120 $css_classes = array(1121 'cat-item',1122 'cat-item-' . $category->term_id,1123 );1124 1125 if ( ! empty( $args['current_category'] ) ) {1126 // 'current_category' can be an array, so we use `get_terms()`.1127 $_current_terms = get_terms( $category->taxonomy, array(1128 'include' => $args['current_category'],1129 'hide_empty' => false,1130 ) );1131 1132 foreach ( $_current_terms as $_current_term ) {1133 if ( $category->term_id == $_current_term->term_id ) {1134 $css_classes[] = 'current-cat';1135 } elseif ( $category->term_id == $_current_term->parent ) {1136 $css_classes[] = 'current-cat-parent';1137 }1138 }1139 }1140 1141 /**1142 * Filter the list of CSS classes to include with each category in the list.1143 *1144 * @since 4.2.01145 *1146 * @see wp_list_categories()1147 *1148 * @param array $css_classes An array of CSS classes to be applied to each list item.1149 * @param object $category Category data object.1150 * @param int $depth Depth of page, used for padding.1151 * @param array $args An array of wp_list_categories() arguments.1152 */1153 $css_classes = implode( ' ', apply_filters( 'category_css_class', $css_classes, $category, $depth, $args ) );1154 1155 $output .= ' class="' . $css_classes . '"';1156 $output .= ">$link\n";1157 } else {1158 $output .= "\t$link<br />\n";1159 }1160 }1161 1162 /**1163 * Ends the element output, if needed.1164 *1165 * @see Walker::end_el()1166 *1167 * @since 2.1.01168 *1169 * @param string $output Passed by reference. Used to append additional content.1170 * @param object $page Not used.1171 * @param int $depth Depth of category. Not used.1172 * @param array $args An array of arguments. Only uses 'list' for whether should append to output. @see wp_list_categories()1173 */1174 public function end_el( &$output, $page, $depth = 0, $args = array() ) {1175 if ( 'list' != $args['style'] )1176 return;1177 1178 $output .= "</li>\n";1179 }1180 1181 }1182 1183 /**1184 * Create HTML dropdown list of Categories.1185 *1186 * @package WordPress1187 * @since 2.1.01188 * @uses Walker1189 */1190 class Walker_CategoryDropdown extends Walker {1191 /**1192 * @see Walker::$tree_type1193 * @since 2.1.01194 * @var string1195 */1196 public $tree_type = 'category';1197 1198 /**1199 * @see Walker::$db_fields1200 * @since 2.1.01201 * @todo Decouple this1202 * @var array1203 */1204 public $db_fields = array ('parent' => 'parent', 'id' => 'term_id');1205 1206 /**1207 * Start the element output.1208 *1209 * @see Walker::start_el()1210 * @since 2.1.01211 *1212 * @param string $output Passed by reference. Used to append additional content.1213 * @param object $category Category data object.1214 * @param int $depth Depth of category. Used for padding.1215 * @param array $args Uses 'selected', 'show_count', and 'value_field' keys, if they exist.1216 * See {@see wp_dropdown_categories()}.1217 */1218 public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {1219 $pad = str_repeat(' ', $depth * 3);1220 1221 /** This filter is documented in wp-includes/category-template.php */1222 $cat_name = apply_filters( 'list_cats', $category->name, $category );1223 1224 if ( isset( $args['value_field'] ) && isset( $category->{$args['value_field']} ) ) {1225 $value_field = $args['value_field'];1226 } else {1227 $value_field = 'term_id';1228 }1229 1230 $output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr( $category->{$value_field} ) . "\"";1231 1232 // Type-juggling causes false matches, so we force everything to a string.1233 if ( (string) $category->{$value_field} === (string) $args['selected'] )1234 $output .= ' selected="selected"';1235 $output .= '>';1236 $output .= $pad.$cat_name;1237 if ( $args['show_count'] )1238 $output .= ' ('. number_format_i18n( $category->count ) .')';1239 $output .= "</option>\n";1240 }1241 }1242 1243 975 // 1244 976 // Tags -
trunk/src/wp-includes/category.php
r32568 r34110 6 6 */ 7 7 8 /** 9 * Retrieve list of category objects. 10 * 11 * If you change the type to 'link' in the arguments, then the link categories 12 * will be returned instead. Also all categories will be updated to be backwards 13 * compatible with pre-2.3 plugins and themes. 14 * 15 * @since 2.1.0 16 * @see get_terms() Type of arguments that can be changed. 17 * @link https://codex.wordpress.org/Function_Reference/get_categories 18 * 19 * @param string|array $args Optional. Change the defaults retrieving categories. 20 * @return array List of categories. 21 */ 22 function get_categories( $args = '' ) { 23 $defaults = array( 'taxonomy' => 'category' ); 24 $args = wp_parse_args( $args, $defaults ); 8 /** Core category functionality */ 9 require_once( ABSPATH . WPINC . '/category-functions.php' ); 25 10 26 $taxonomy = $args['taxonomy']; 11 /** Walker_Category class */ 12 require_once( ABSPATH . WPINC . '/class-walker-category.php' ); 27 13 28 /** 29 * Filter the taxonomy used to retrieve terms when calling {@see get_categories()}. 30 * 31 * @since 2.7.0 32 * 33 * @param string $taxonomy Taxonomy to retrieve terms from. 34 * @param array $args An array of arguments. See {@see get_terms()}. 35 */ 36 $taxonomy = apply_filters( 'get_categories_taxonomy', $taxonomy, $args ); 37 38 // Back compat 39 if ( isset($args['type']) && 'link' == $args['type'] ) { 40 _deprecated_argument( __FUNCTION__, '3.0', '' ); 41 $taxonomy = $args['taxonomy'] = 'link_category'; 42 } 43 44 $categories = (array) get_terms( $taxonomy, $args ); 45 46 foreach ( array_keys( $categories ) as $k ) 47 _make_cat_compat( $categories[$k] ); 48 49 return $categories; 50 } 51 52 /** 53 * Retrieves category data given a category ID or category object. 54 * 55 * If you pass the $category parameter an object, which is assumed to be the 56 * category row object retrieved the database. It will cache the category data. 57 * 58 * If you pass $category an integer of the category ID, then that category will 59 * be retrieved from the database, if it isn't already cached, and pass it back. 60 * 61 * If you look at get_term(), then both types will be passed through several 62 * filters and finally sanitized based on the $filter parameter value. 63 * 64 * The category will converted to maintain backwards compatibility. 65 * 66 * @since 1.5.1 67 * 68 * @param int|object $category Category ID or Category row object 69 * @param string $output Optional. Constant OBJECT, ARRAY_A, or ARRAY_N 70 * @param string $filter Optional. Default is raw or no WordPress defined filter will applied. 71 * @return object|array|WP_Error|null Category data in type defined by $output parameter. 72 * WP_Error if $category is empty, null if it does not exist. 73 */ 74 function get_category( $category, $output = OBJECT, $filter = 'raw' ) { 75 $category = get_term( $category, 'category', $output, $filter ); 76 77 if ( is_wp_error( $category ) ) 78 return $category; 79 80 _make_cat_compat( $category ); 81 82 return $category; 83 } 84 85 /** 86 * Retrieve category based on URL containing the category slug. 87 * 88 * Breaks the $category_path parameter up to get the category slug. 89 * 90 * Tries to find the child path and will return it. If it doesn't find a 91 * match, then it will return the first category matching slug, if $full_match, 92 * is set to false. If it does not, then it will return null. 93 * 94 * It is also possible that it will return a WP_Error object on failure. Check 95 * for it when using this function. 96 * 97 * @since 2.1.0 98 * 99 * @param string $category_path URL containing category slugs. 100 * @param bool $full_match Optional. Whether full path should be matched. 101 * @param string $output Optional. Constant OBJECT, ARRAY_A, or ARRAY_N 102 * @return object|array|WP_Error|void Type is based on $output value. 103 */ 104 function get_category_by_path( $category_path, $full_match = true, $output = OBJECT ) { 105 $category_path = rawurlencode( urldecode( $category_path ) ); 106 $category_path = str_replace( '%2F', '/', $category_path ); 107 $category_path = str_replace( '%20', ' ', $category_path ); 108 $category_paths = '/' . trim( $category_path, '/' ); 109 $leaf_path = sanitize_title( basename( $category_paths ) ); 110 $category_paths = explode( '/', $category_paths ); 111 $full_path = ''; 112 foreach ( (array) $category_paths as $pathdir ) { 113 $full_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title( $pathdir ); 114 } 115 $categories = get_terms( 'category', array('get' => 'all', 'slug' => $leaf_path) ); 116 117 if ( empty( $categories ) ) { 118 return; 119 } 120 121 foreach ( $categories as $category ) { 122 $path = '/' . $leaf_path; 123 $curcategory = $category; 124 while ( ( $curcategory->parent != 0 ) && ( $curcategory->parent != $curcategory->term_id ) ) { 125 $curcategory = get_term( $curcategory->parent, 'category' ); 126 if ( is_wp_error( $curcategory ) ) { 127 return $curcategory; 128 } 129 $path = '/' . $curcategory->slug . $path; 130 } 131 132 if ( $path == $full_path ) { 133 $category = get_term( $category->term_id, 'category', $output ); 134 _make_cat_compat( $category ); 135 return $category; 136 } 137 } 138 139 // If full matching is not required, return the first cat that matches the leaf. 140 if ( ! $full_match ) { 141 $category = get_term( reset( $categories )->term_id, 'category', $output ); 142 _make_cat_compat( $category ); 143 return $category; 144 } 145 } 146 147 /** 148 * Retrieve category object by category slug. 149 * 150 * @since 2.3.0 151 * 152 * @param string $slug The category slug. 153 * @return object Category data object 154 */ 155 function get_category_by_slug( $slug ) { 156 $category = get_term_by( 'slug', $slug, 'category' ); 157 if ( $category ) 158 _make_cat_compat( $category ); 159 160 return $category; 161 } 162 163 /** 164 * Retrieve the ID of a category from its name. 165 * 166 * @since 1.0.0 167 * 168 * @param string $cat_name Category name. 169 * @return int 0, if failure and ID of category on success. 170 */ 171 function get_cat_ID( $cat_name ) { 172 $cat = get_term_by( 'name', $cat_name, 'category' ); 173 if ( $cat ) 174 return $cat->term_id; 175 return 0; 176 } 177 178 /** 179 * Retrieve the name of a category from its ID. 180 * 181 * @since 1.0.0 182 * 183 * @param int $cat_id Category ID 184 * @return string Category name, or an empty string if category doesn't exist. 185 */ 186 function get_cat_name( $cat_id ) { 187 $cat_id = (int) $cat_id; 188 $category = get_term( $cat_id, 'category' ); 189 if ( ! $category || is_wp_error( $category ) ) 190 return ''; 191 return $category->name; 192 } 193 194 /** 195 * Check if a category is an ancestor of another category. 196 * 197 * You can use either an id or the category object for both parameters. If you 198 * use an integer the category will be retrieved. 199 * 200 * @since 2.1.0 201 * 202 * @param int|object $cat1 ID or object to check if this is the parent category. 203 * @param int|object $cat2 The child category. 204 * @return bool Whether $cat2 is child of $cat1 205 */ 206 function cat_is_ancestor_of( $cat1, $cat2 ) { 207 return term_is_ancestor_of( $cat1, $cat2, 'category' ); 208 } 209 210 /** 211 * Sanitizes category data based on context. 212 * 213 * @since 2.3.0 214 * 215 * @param object|array $category Category data 216 * @param string $context Optional. Default is 'display'. 217 * @return object|array Same type as $category with sanitized data for safe use. 218 */ 219 function sanitize_category( $category, $context = 'display' ) { 220 return sanitize_term( $category, 'category', $context ); 221 } 222 223 /** 224 * Sanitizes data in single category key field. 225 * 226 * @since 2.3.0 227 * 228 * @param string $field Category key to sanitize 229 * @param mixed $value Category value to sanitize 230 * @param int $cat_id Category ID 231 * @param string $context What filter to use, 'raw', 'display', etc. 232 * @return mixed Same type as $value after $value has been sanitized. 233 */ 234 function sanitize_category_field( $field, $value, $cat_id, $context ) { 235 return sanitize_term_field( $field, $value, $cat_id, 'category', $context ); 236 } 237 238 /* Tags */ 239 240 /** 241 * Retrieves all post tags. 242 * 243 * @since 2.3.0 244 * @see get_terms() For list of arguments to pass. 245 * 246 * @param string|array $args Tag arguments to use when retrieving tags. 247 * @return array List of tags. 248 */ 249 function get_tags( $args = '' ) { 250 $tags = get_terms( 'post_tag', $args ); 251 252 if ( empty( $tags ) ) { 253 $return = array(); 254 return $return; 255 } 256 257 /** 258 * Filter the array of term objects returned for the 'post_tag' taxonomy. 259 * 260 * @since 2.3.0 261 * 262 * @param array $tags Array of 'post_tag' term objects. 263 * @param array $args An array of arguments. @see get_terms() 264 */ 265 $tags = apply_filters( 'get_tags', $tags, $args ); 266 return $tags; 267 } 268 269 /** 270 * Retrieve post tag by tag ID or tag object. 271 * 272 * If you pass the $tag parameter an object, which is assumed to be the tag row 273 * object retrieved the database. It will cache the tag data. 274 * 275 * If you pass $tag an integer of the tag ID, then that tag will 276 * be retrieved from the database, if it isn't already cached, and pass it back. 277 * 278 * If you look at get_term(), then both types will be passed through several 279 * filters and finally sanitized based on the $filter parameter value. 280 * 281 * @since 2.3.0 282 * 283 * @param int|object $tag 284 * @param string $output Optional. Constant OBJECT, ARRAY_A, or ARRAY_N 285 * @param string $filter Optional. Default is raw or no WordPress defined filter will applied. 286 * @return object|array|WP_Error|null Tag data in type defined by $output parameter. WP_Error if $tag is empty, null if it does not exist. 287 */ 288 function get_tag( $tag, $output = OBJECT, $filter = 'raw' ) { 289 return get_term( $tag, 'post_tag', $output, $filter ); 290 } 291 292 /* Cache */ 293 294 /** 295 * Remove the category cache data based on ID. 296 * 297 * @since 2.1.0 298 * 299 * @param int $id Category ID 300 */ 301 function clean_category_cache( $id ) { 302 clean_term_cache( $id, 'category' ); 303 } 304 305 /** 306 * Update category structure to old pre 2.3 from new taxonomy structure. 307 * 308 * This function was added for the taxonomy support to update the new category 309 * structure with the old category one. This will maintain compatibility with 310 * plugins and themes which depend on the old key or property names. 311 * 312 * The parameter should only be passed a variable and not create the array or 313 * object inline to the parameter. The reason for this is that parameter is 314 * passed by reference and PHP will fail unless it has the variable. 315 * 316 * There is no return value, because everything is updated on the variable you 317 * pass to it. This is one of the features with using pass by reference in PHP. 318 * 319 * @since 2.3.0 320 * @access private 321 * 322 * @param array|object $category Category Row object or array 323 */ 324 function _make_cat_compat( &$category ) { 325 if ( is_object( $category ) && ! is_wp_error( $category ) ) { 326 $category->cat_ID = &$category->term_id; 327 $category->category_count = &$category->count; 328 $category->category_description = &$category->description; 329 $category->cat_name = &$category->name; 330 $category->category_nicename = &$category->slug; 331 $category->category_parent = &$category->parent; 332 } elseif ( is_array( $category ) && isset( $category['term_id'] ) ) { 333 $category['cat_ID'] = &$category['term_id']; 334 $category['category_count'] = &$category['count']; 335 $category['category_description'] = &$category['description']; 336 $category['cat_name'] = &$category['name']; 337 $category['category_nicename'] = &$category['slug']; 338 $category['category_parent'] = &$category['parent']; 339 } 340 } 14 /** Walker_CategoryDropdown class */ 15 require_once( ABSPATH . WPINC . '/class-walker-category-dropdown.php' ); -
trunk/src/wp-includes/class-walker-category-dropdown.php
r34109 r34110 1 1 <?php 2 2 /** 3 * Category Template Tags and API.3 * Category API: Walker_CategoryDropdown class 4 4 * 5 5 * @package WordPress 6 6 * @subpackage Template 7 7 */ 8 9 /**10 * Retrieve category link URL.11 *12 * @since 1.0.013 * @see get_term_link()14 *15 * @param int|object $category Category ID or object.16 * @return string Link on success, empty string if category does not exist.17 */18 function get_category_link( $category ) {19 if ( ! is_object( $category ) )20 $category = (int) $category;21 22 $category = get_term_link( $category, 'category' );23 24 if ( is_wp_error( $category ) )25 return '';26 27 return $category;28 }29 30 /**31 * Retrieve category parents with separator.32 *33 * @since 1.2.034 *35 * @param int $id Category ID.36 * @param bool $link Optional, default is false. Whether to format with link.37 * @param string $separator Optional, default is '/'. How to separate categories.38 * @param bool $nicename Optional, default is false. Whether to use nice name for display.39 * @param array $visited Optional. Already linked to categories to prevent duplicates.40 * @return string|WP_Error A list of category parents on success, WP_Error on failure.41 */42 function get_category_parents( $id, $link = false, $separator = '/', $nicename = false, $visited = array() ) {43 $chain = '';44 $parent = get_term( $id, 'category' );45 if ( is_wp_error( $parent ) )46 return $parent;47 48 if ( $nicename )49 $name = $parent->slug;50 else51 $name = $parent->name;52 53 if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) {54 $visited[] = $parent->parent;55 $chain .= get_category_parents( $parent->parent, $link, $separator, $nicename, $visited );56 }57 58 if ( $link )59 $chain .= '<a href="' . esc_url( get_category_link( $parent->term_id ) ) . '">'.$name.'</a>' . $separator;60 else61 $chain .= $name.$separator;62 return $chain;63 }64 65 /**66 * Retrieve post categories.67 *68 * This tag may be used outside The Loop by passing a post id as the parameter.69 *70 * Note: This function only returns results from the default "category" taxonomy.71 * For custom taxonomies use get_the_terms().72 *73 * @since 0.7174 *75 * @param int $id Optional, default to current post ID. The post ID.76 * @return array Array of objects, one for each category assigned to the post.77 */78 function get_the_category( $id = false ) {79 $categories = get_the_terms( $id, 'category' );80 if ( ! $categories || is_wp_error( $categories ) )81 $categories = array();82 83 $categories = array_values( $categories );84 85 foreach ( array_keys( $categories ) as $key ) {86 _make_cat_compat( $categories[$key] );87 }88 89 /**90 * Filter the array of categories to return for a post.91 *92 * @since 3.1.093 *94 * @param array $categories An array of categories to return for the post.95 */96 return apply_filters( 'get_the_categories', $categories );97 }98 99 /**100 * Sort categories by name.101 *102 * Used by usort() as a callback, should not be used directly. Can actually be103 * used to sort any term object.104 *105 * @since 2.3.0106 * @access private107 *108 * @param object $a109 * @param object $b110 * @return int111 */112 function _usort_terms_by_name( $a, $b ) {113 return strcmp( $a->name, $b->name );114 }115 116 /**117 * Sort categories by ID.118 *119 * Used by usort() as a callback, should not be used directly. Can actually be120 * used to sort any term object.121 *122 * @since 2.3.0123 * @access private124 *125 * @param object $a126 * @param object $b127 * @return int128 */129 function _usort_terms_by_ID( $a, $b ) {130 if ( $a->term_id > $b->term_id )131 return 1;132 elseif ( $a->term_id < $b->term_id )133 return -1;134 else135 return 0;136 }137 138 /**139 * Retrieve category name based on category ID.140 *141 * @since 0.71142 *143 * @param int $cat_ID Category ID.144 * @return string|WP_Error Category name on success, WP_Error on failure.145 */146 function get_the_category_by_ID( $cat_ID ) {147 $cat_ID = (int) $cat_ID;148 $category = get_term( $cat_ID, 'category' );149 150 if ( is_wp_error( $category ) )151 return $category;152 153 return ( $category ) ? $category->name : '';154 }155 156 /**157 * Retrieve category list in either HTML list or custom format.158 *159 * @since 1.5.1160 *161 * @global WP_Rewrite $wp_rewrite162 *163 * @param string $separator Optional, default is empty string. Separator for between the categories.164 * @param string $parents Optional. How to display the parents.165 * @param int $post_id Optional. Post ID to retrieve categories.166 * @return string167 */168 function get_the_category_list( $separator = '', $parents='', $post_id = false ) {169 global $wp_rewrite;170 if ( ! is_object_in_taxonomy( get_post_type( $post_id ), 'category' ) ) {171 /** This filter is documented in wp-includes/category-template.php */172 return apply_filters( 'the_category', '', $separator, $parents );173 }174 175 $categories = get_the_category( $post_id );176 if ( empty( $categories ) ) {177 /** This filter is documented in wp-includes/category-template.php */178 return apply_filters( 'the_category', __( 'Uncategorized' ), $separator, $parents );179 }180 181 $rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';182 183 $thelist = '';184 if ( '' == $separator ) {185 $thelist .= '<ul class="post-categories">';186 foreach ( $categories as $category ) {187 $thelist .= "\n\t<li>";188 switch ( strtolower( $parents ) ) {189 case 'multiple':190 if ( $category->parent )191 $thelist .= get_category_parents( $category->parent, true, $separator );192 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';193 break;194 case 'single':195 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';196 if ( $category->parent )197 $thelist .= get_category_parents( $category->parent, false, $separator );198 $thelist .= $category->name.'</a></li>';199 break;200 case '':201 default:202 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';203 }204 }205 $thelist .= '</ul>';206 } else {207 $i = 0;208 foreach ( $categories as $category ) {209 if ( 0 < $i )210 $thelist .= $separator;211 switch ( strtolower( $parents ) ) {212 case 'multiple':213 if ( $category->parent )214 $thelist .= get_category_parents( $category->parent, true, $separator );215 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a>';216 break;217 case 'single':218 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';219 if ( $category->parent )220 $thelist .= get_category_parents( $category->parent, false, $separator );221 $thelist .= "$category->name</a>";222 break;223 case '':224 default:225 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a>';226 }227 ++$i;228 }229 }230 231 /**232 * Filter the category or list of categories.233 *234 * @since 1.2.0235 *236 * @param array $thelist List of categories for the current post.237 * @param string $separator Separator used between the categories.238 * @param string $parents How to display the category parents. Accepts 'multiple',239 * 'single', or empty.240 */241 return apply_filters( 'the_category', $thelist, $separator, $parents );242 }243 244 /**245 * Check if the current post in within any of the given categories.246 *247 * The given categories are checked against the post's categories' term_ids, names and slugs.248 * Categories given as integers will only be checked against the post's categories' term_ids.249 *250 * Prior to v2.5 of WordPress, category names were not supported.251 * Prior to v2.7, category slugs were not supported.252 * Prior to v2.7, only one category could be compared: in_category( $single_category ).253 * Prior to v2.7, this function could only be used in the WordPress Loop.254 * As of 2.7, the function can be used anywhere if it is provided a post ID or post object.255 *256 * @since 1.2.0257 *258 * @param int|string|array $category Category ID, name or slug, or array of said.259 * @param int|object $post Optional. Post to check instead of the current post. (since 2.7.0)260 * @return bool True if the current post is in any of the given categories.261 */262 function in_category( $category, $post = null ) {263 if ( empty( $category ) )264 return false;265 266 return has_category( $category, $post );267 }268 269 /**270 * Display the category list for the post.271 *272 * @since 0.71273 *274 * @param string $separator Optional, default is empty string. Separator for between the categories.275 * @param string $parents Optional. How to display the parents.276 * @param int $post_id Optional. Post ID to retrieve categories.277 */278 function the_category( $separator = '', $parents='', $post_id = false ) {279 echo get_the_category_list( $separator, $parents, $post_id );280 }281 282 /**283 * Retrieve category description.284 *285 * @since 1.0.0286 *287 * @param int $category Optional. Category ID. Will use global category ID by default.288 * @return string Category description, available.289 */290 function category_description( $category = 0 ) {291 return term_description( $category, 'category' );292 }293 294 /**295 * Display or retrieve the HTML dropdown list of categories.296 *297 * The 'hierarchical' argument, which is disabled by default, will override the298 * depth argument, unless it is true. When the argument is false, it will299 * display all of the categories. When it is enabled it will use the value in300 * the 'depth' argument.301 *302 * @since 2.1.0303 * @since 4.2.0 Introduced the `value_field` argument.304 *305 * @param string|array $args {306 * Optional. Array or string of arguments to generate a categories drop-down element.307 *308 * @type string $show_option_all Text to display for showing all categories. Default empty.309 * @type string $show_option_none Text to display for showing no categories. Default empty.310 * @type string $option_none_value Value to use when no category is selected. Default empty.311 * @type string $orderby Which column to use for ordering categories. See get_terms() for a list312 * of accepted values. Default 'id' (term_id).313 * @type string $order Whether to order terms in ascending or descending order. Accepts 'ASC'314 * or 'DESC'. Default 'ASC'.315 * @type bool $pad_counts See get_terms() for an argument description. Default false.316 * @type bool|int $show_count Whether to include post counts. Accepts 0, 1, or their bool equivalents.317 * Default 0.318 * @type bool|int $hide_empty Whether to hide categories that don't have any posts. Accepts 0, 1, or319 * their bool equivalents. Default 1.320 * @type int $child_of Term ID to retrieve child terms of. See get_terms(). Default 0.321 * @type array|string $exclude Array or comma/space-separated string of term ids to exclude.322 * If `$include` is non-empty, `$exclude` is ignored. Default empty array.323 * @type bool|int $echo Whether to echo or return the generated markup. Accepts 0, 1, or their324 * bool equivalents. Default 1.325 * @type bool|int $hierarchical Whether to traverse the taxonomy hierarchy. Accepts 0, 1, or their bool326 * equivalents. Default 0.327 * @type int $depth Maximum depth. Default 0.328 * @type int $tab_index Tab index for the select element. Default 0 (no tabindex).329 * @type string $name Value for the 'name' attribute of the select element. Default 'cat'.330 * @type string $id Value for the 'id' attribute of the select element. Defaults to the value331 * of `$name`.332 * @type string $class Value for the 'class' attribute of the select element. Default 'postform'.333 * @type int|string $selected Value of the option that should be selected. Default 0.334 * @type string $value_field Term field that should be used to populate the 'value' attribute335 * of the option elements. Accepts any valid term field: 'term_id', 'name',336 * 'slug', 'term_group', 'term_taxonomy_id', 'taxonomy', 'description',337 * 'parent', 'count'. Default 'term_id'.338 * @type string $taxonomy Name of the category to retrieve. Default 'category'.339 * @type bool $hide_if_empty True to skip generating markup if no categories are found.340 * Default false (create select element even if no categories are found).341 * }342 * @return string HTML content only if 'echo' argument is 0.343 */344 function wp_dropdown_categories( $args = '' ) {345 $defaults = array(346 'show_option_all' => '', 'show_option_none' => '',347 'orderby' => 'id', 'order' => 'ASC',348 'show_count' => 0,349 'hide_empty' => 1, 'child_of' => 0,350 'exclude' => '', 'echo' => 1,351 'selected' => 0, 'hierarchical' => 0,352 'name' => 'cat', 'id' => '',353 'class' => 'postform', 'depth' => 0,354 'tab_index' => 0, 'taxonomy' => 'category',355 'hide_if_empty' => false, 'option_none_value' => -1,356 'value_field' => 'term_id',357 );358 359 $defaults['selected'] = ( is_category() ) ? get_query_var( 'cat' ) : 0;360 361 // Back compat.362 if ( isset( $args['type'] ) && 'link' == $args['type'] ) {363 _deprecated_argument( __FUNCTION__, '3.0', '' );364 $args['taxonomy'] = 'link_category';365 }366 367 $r = wp_parse_args( $args, $defaults );368 $option_none_value = $r['option_none_value'];369 370 if ( ! isset( $r['pad_counts'] ) && $r['show_count'] && $r['hierarchical'] ) {371 $r['pad_counts'] = true;372 }373 374 $tab_index = $r['tab_index'];375 376 $tab_index_attribute = '';377 if ( (int) $tab_index > 0 ) {378 $tab_index_attribute = " tabindex=\"$tab_index\"";379 }380 381 // Avoid clashes with the 'name' param of get_terms().382 $get_terms_args = $r;383 unset( $get_terms_args['name'] );384 $categories = get_terms( $r['taxonomy'], $get_terms_args );385 386 $name = esc_attr( $r['name'] );387 $class = esc_attr( $r['class'] );388 $id = $r['id'] ? esc_attr( $r['id'] ) : $name;389 390 if ( ! $r['hide_if_empty'] || ! empty( $categories ) ) {391 $output = "<select name='$name' id='$id' class='$class' $tab_index_attribute>\n";392 } else {393 $output = '';394 }395 if ( empty( $categories ) && ! $r['hide_if_empty'] && ! empty( $r['show_option_none'] ) ) {396 397 /**398 * Filter a taxonomy drop-down display element.399 *400 * A variety of taxonomy drop-down display elements can be modified401 * just prior to display via this filter. Filterable arguments include402 * 'show_option_none', 'show_option_all', and various forms of the403 * term name.404 *405 * @since 1.2.0406 *407 * @see wp_dropdown_categories()408 *409 * @param string $element Taxonomy element to list.410 */411 $show_option_none = apply_filters( 'list_cats', $r['show_option_none'] );412 $output .= "\t<option value='" . esc_attr( $option_none_value ) . "' selected='selected'>$show_option_none</option>\n";413 }414 415 if ( ! empty( $categories ) ) {416 417 if ( $r['show_option_all'] ) {418 419 /** This filter is documented in wp-includes/category-template.php */420 $show_option_all = apply_filters( 'list_cats', $r['show_option_all'] );421 $selected = ( '0' === strval($r['selected']) ) ? " selected='selected'" : '';422 $output .= "\t<option value='0'$selected>$show_option_all</option>\n";423 }424 425 if ( $r['show_option_none'] ) {426 427 /** This filter is documented in wp-includes/category-template.php */428 $show_option_none = apply_filters( 'list_cats', $r['show_option_none'] );429 $selected = selected( $option_none_value, $r['selected'], false );430 $output .= "\t<option value='" . esc_attr( $option_none_value ) . "'$selected>$show_option_none</option>\n";431 }432 433 if ( $r['hierarchical'] ) {434 $depth = $r['depth']; // Walk the full depth.435 } else {436 $depth = -1; // Flat.437 }438 $output .= walk_category_dropdown_tree( $categories, $depth, $r );439 }440 441 if ( ! $r['hide_if_empty'] || ! empty( $categories ) ) {442 $output .= "</select>\n";443 }444 /**445 * Filter the taxonomy drop-down output.446 *447 * @since 2.1.0448 *449 * @param string $output HTML output.450 * @param array $r Arguments used to build the drop-down.451 */452 $output = apply_filters( 'wp_dropdown_cats', $output, $r );453 454 if ( $r['echo'] ) {455 echo $output;456 }457 return $output;458 }459 460 /**461 * Display or retrieve the HTML list of categories.462 *463 * @since 2.1.0464 * @since 4.4.0 Introduced the `hide_title_if_empty` argument. The `current_category` argument was modified to465 * optionally accept an array of values.466 *467 * @param string|array $args {468 * Array of optional arguments.469 *470 * @type string $show_option_all Text to display for showing all categories. Default empty string.471 * @type string $show_option_none Text to display for the 'no categories' option.472 * Default 'No categories'.473 * @type string $orderby The column to use for ordering categories. Default 'ID'.474 * @type string $order Which direction to order categories. Accepts 'ASC' or 'DESC'.475 * Default 'ASC'.476 * @type bool|int $show_count Whether to show how many posts are in the category. Default 0.477 * @type bool|int $hide_empty Whether to hide categories that don't have any posts attached to them.478 * Default 1.479 * @type bool|int $use_desc_for_title Whether to use the category description as the title attribute.480 * Default 1.481 * @type string $feed Text to use for the feed link. Default 'Feed for all posts filed482 * under [cat name]'.483 * @type string $feed_type Feed type. Used to build feed link. See {@link get_term_feed_link()}.484 * Default empty string (default feed).485 * @type string $feed_image URL of an image to use for the feed link. Default empty string.486 * @type int $child_of Term ID to retrieve child terms of. See {@link get_terms()}. Default 0.487 * @type array|string $exclude Array or comma/space-separated string of term IDs to exclude.488 * See {@link get_terms()}. Default empty string.489 * @type array|string $exclude_tree Array or comma/space-separated string of term IDs to exclude, along490 * with their descendants. See {@link get_terms()}. Default empty string.491 * @type bool|int $echo True to echo markup, false to return it. Default 1.492 * @type int|array $current_category ID of category, or array of IDs of categories, that should get the493 * 'current-cat' class. Default 0.494 * @type bool $hierarchical Whether to include terms that have non-empty descendants.495 * See {@link get_terms()}. Default true.496 * @type string $title_li Text to use for the list title `<li>` element. Pass an empty string497 * to disable. Default 'Categories'.498 * @type bool $hide_title_if_empty Whether to hide the `$title_li` element if there are no terms in499 * the list. Default false (title will always be shown).500 * @type int $depth Category depth. Used for tab indentation. Default 0.501 * @type string $taxonomy Taxonomy name. Default 'category'.502 * }503 * @return false|string HTML content only if 'echo' argument is 0.504 */505 function wp_list_categories( $args = '' ) {506 $defaults = array(507 'show_option_all' => '', 'show_option_none' => __('No categories'),508 'orderby' => 'name', 'order' => 'ASC',509 'style' => 'list',510 'show_count' => 0, 'hide_empty' => 1,511 'use_desc_for_title' => 1, 'child_of' => 0,512 'feed' => '', 'feed_type' => '',513 'feed_image' => '', 'exclude' => '',514 'exclude_tree' => '', 'current_category' => 0,515 'hierarchical' => true, 'title_li' => __( 'Categories' ),516 'hide_title_if_empty' => false,517 'echo' => 1, 'depth' => 0,518 'taxonomy' => 'category'519 );520 521 $r = wp_parse_args( $args, $defaults );522 523 if ( !isset( $r['pad_counts'] ) && $r['show_count'] && $r['hierarchical'] )524 $r['pad_counts'] = true;525 526 if ( true == $r['hierarchical'] ) {527 $r['exclude_tree'] = $r['exclude'];528 $r['exclude'] = '';529 }530 531 if ( ! isset( $r['class'] ) )532 $r['class'] = ( 'category' == $r['taxonomy'] ) ? 'categories' : $r['taxonomy'];533 534 if ( ! taxonomy_exists( $r['taxonomy'] ) ) {535 return false;536 }537 538 $show_option_all = $r['show_option_all'];539 $show_option_none = $r['show_option_none'];540 541 $categories = get_categories( $r );542 543 $output = '';544 if ( $r['title_li'] && 'list' == $r['style'] && ( ! empty( $categories ) || ! $r['hide_title_if_empty'] ) ) {545 $output = '<li class="' . esc_attr( $r['class'] ) . '">' . $r['title_li'] . '<ul>';546 }547 if ( empty( $categories ) ) {548 if ( ! empty( $show_option_none ) ) {549 if ( 'list' == $r['style'] ) {550 $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';551 } else {552 $output .= $show_option_none;553 }554 }555 } else {556 if ( ! empty( $show_option_all ) ) {557 558 $posts_page = '';559 560 // For taxonomies that belong only to custom post types, point to a valid archive.561 $taxonomy_object = get_taxonomy( $r['taxonomy'] );562 if ( ! in_array( 'post', $taxonomy_object->object_type ) && ! in_array( 'page', $taxonomy_object->object_type ) ) {563 foreach ( $taxonomy_object->object_type as $object_type ) {564 $_object_type = get_post_type_object( $object_type );565 566 // Grab the first one.567 if ( ! empty( $_object_type->has_archive ) ) {568 $posts_page = get_post_type_archive_link( $object_type );569 break;570 }571 }572 }573 574 // Fallback for the 'All' link is the front page.575 if ( ! $posts_page ) {576 $posts_page = 'page' == get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) ? get_permalink( get_option( 'page_for_posts' ) ) : home_url( '/' );577 }578 579 $posts_page = esc_url( $posts_page );580 if ( 'list' == $r['style'] ) {581 $output .= "<li class='cat-item-all'><a href='$posts_page'>$show_option_all</a></li>";582 } else {583 $output .= "<a href='$posts_page'>$show_option_all</a>";584 }585 }586 587 if ( empty( $r['current_category'] ) && ( is_category() || is_tax() || is_tag() ) ) {588 $current_term_object = get_queried_object();589 if ( $current_term_object && $r['taxonomy'] === $current_term_object->taxonomy ) {590 $r['current_category'] = get_queried_object_id();591 }592 }593 594 if ( $r['hierarchical'] ) {595 $depth = $r['depth'];596 } else {597 $depth = -1; // Flat.598 }599 $output .= walk_category_tree( $categories, $depth, $r );600 }601 602 if ( $r['title_li'] && 'list' == $r['style'] )603 $output .= '</ul></li>';604 605 /**606 * Filter the HTML output of a taxonomy list.607 *608 * @since 2.1.0609 *610 * @param string $output HTML output.611 * @param array $args An array of taxonomy-listing arguments.612 */613 $html = apply_filters( 'wp_list_categories', $output, $args );614 615 if ( $r['echo'] ) {616 echo $html;617 } else {618 return $html;619 }620 }621 622 /**623 * Display tag cloud.624 *625 * The text size is set by the 'smallest' and 'largest' arguments, which will626 * use the 'unit' argument value for the CSS text size unit. The 'format'627 * argument can be 'flat' (default), 'list', or 'array'. The flat value for the628 * 'format' argument will separate tags with spaces. The list value for the629 * 'format' argument will format the tags in a UL HTML list. The array value for630 * the 'format' argument will return in PHP array type format.631 *632 * The 'orderby' argument will accept 'name' or 'count' and defaults to 'name'.633 * The 'order' is the direction to sort, defaults to 'ASC' and can be 'DESC'.634 *635 * The 'number' argument is how many tags to return. By default, the limit will636 * be to return the top 45 tags in the tag cloud list.637 *638 * The 'topic_count_text' argument is a nooped plural from _n_noop() to generate the639 * text for the tooltip of the tag link.640 *641 * The 'topic_count_text_callback' argument is a function, which given the count642 * of the posts with that tag returns a text for the tooltip of the tag link.643 *644 * The 'post_type' argument is used only when 'link' is set to 'edit'. It determines the post_type645 * passed to edit.php for the popular tags edit links.646 *647 * The 'exclude' and 'include' arguments are used for the {@link get_tags()}648 * function. Only one should be used, because only one will be used and the649 * other ignored, if they are both set.650 *651 * @since 2.3.0652 *653 * @param array|string|null $args Optional. Override default arguments.654 * @return void|array Generated tag cloud, only if no failures and 'array' is set for the 'format' argument.655 * Otherwise, this function outputs the tag cloud.656 */657 function wp_tag_cloud( $args = '' ) {658 $defaults = array(659 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45,660 'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC',661 'exclude' => '', 'include' => '', 'link' => 'view', 'taxonomy' => 'post_tag', 'post_type' => '', 'echo' => true662 );663 $args = wp_parse_args( $args, $defaults );664 665 $tags = get_terms( $args['taxonomy'], array_merge( $args, array( 'orderby' => 'count', 'order' => 'DESC' ) ) ); // Always query top tags666 667 if ( empty( $tags ) || is_wp_error( $tags ) )668 return;669 670 foreach ( $tags as $key => $tag ) {671 if ( 'edit' == $args['link'] )672 $link = get_edit_term_link( $tag->term_id, $tag->taxonomy, $args['post_type'] );673 else674 $link = get_term_link( intval($tag->term_id), $tag->taxonomy );675 if ( is_wp_error( $link ) )676 return;677 678 $tags[ $key ]->link = $link;679 $tags[ $key ]->id = $tag->term_id;680 }681 682 $return = wp_generate_tag_cloud( $tags, $args ); // Here's where those top tags get sorted according to $args683 684 /**685 * Filter the tag cloud output.686 *687 * @since 2.3.0688 *689 * @param string $return HTML output of the tag cloud.690 * @param array $args An array of tag cloud arguments.691 */692 $return = apply_filters( 'wp_tag_cloud', $return, $args );693 694 if ( 'array' == $args['format'] || empty($args['echo']) )695 return $return;696 697 echo $return;698 }699 700 /**701 * Default topic count scaling for tag links702 *703 * @param int $count number of posts with that tag704 * @return int scaled count705 */706 function default_topic_count_scale( $count ) {707 return round(log10($count + 1) * 100);708 }709 710 /**711 * Generates a tag cloud (heatmap) from provided data.712 *713 * The text size is set by the 'smallest' and 'largest' arguments, which will714 * use the 'unit' argument value for the CSS text size unit. The 'format'715 * argument can be 'flat' (default), 'list', or 'array'. The flat value for the716 * 'format' argument will separate tags with spaces. The list value for the717 * 'format' argument will format the tags in a UL HTML list. The array value for718 * the 'format' argument will return in PHP array type format.719 *720 * The 'tag_cloud_sort' filter allows you to override the sorting.721 * Passed to the filter: $tags array and $args array, has to return the $tags array722 * after sorting it.723 *724 * The 'orderby' argument will accept 'name' or 'count' and defaults to 'name'.725 * The 'order' is the direction to sort, defaults to 'ASC' and can be 'DESC' or726 * 'RAND'.727 *728 * The 'number' argument is how many tags to return. By default, the limit will729 * be to return the entire tag cloud list.730 *731 * The 'topic_count_text' argument is a nooped plural from _n_noop() to generate the732 * text for the tooltip of the tag link.733 *734 * The 'topic_count_text_callback' argument is a function, which given the count735 * of the posts with that tag returns a text for the tooltip of the tag link.736 *737 * @todo Complete functionality.738 * @since 2.3.0739 *740 * @param array $tags List of tags.741 * @param string|array $args Optional, override default arguments.742 * @return string|array Tag cloud as a string or an array, depending on 'format' argument.743 */744 function wp_generate_tag_cloud( $tags, $args = '' ) {745 $defaults = array(746 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 0,747 'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC',748 'topic_count_text' => null, 'topic_count_text_callback' => null,749 'topic_count_scale_callback' => 'default_topic_count_scale', 'filter' => 1,750 );751 752 $args = wp_parse_args( $args, $defaults );753 754 $return = ( 'array' === $args['format'] ) ? array() : '';755 756 if ( empty( $tags ) ) {757 return $return;758 }759 760 // Juggle topic count tooltips:761 if ( isset( $args['topic_count_text'] ) ) {762 // First look for nooped plural support via topic_count_text.763 $translate_nooped_plural = $args['topic_count_text'];764 } elseif ( ! empty( $args['topic_count_text_callback'] ) ) {765 // Look for the alternative callback style. Ignore the previous default.766 if ( $args['topic_count_text_callback'] === 'default_topic_count_text' ) {767 $translate_nooped_plural = _n_noop( '%s topic', '%s topics' );768 } else {769 $translate_nooped_plural = false;770 }771 } elseif ( isset( $args['single_text'] ) && isset( $args['multiple_text'] ) ) {772 // If no callback exists, look for the old-style single_text and multiple_text arguments.773 $translate_nooped_plural = _n_noop( $args['single_text'], $args['multiple_text'] );774 } else {775 // This is the default for when no callback, plural, or argument is passed in.776 $translate_nooped_plural = _n_noop( '%s topic', '%s topics' );777 }778 779 /**780 * Filter how the items in a tag cloud are sorted.781 *782 * @since 2.8.0783 *784 * @param array $tags Ordered array of terms.785 * @param array $args An array of tag cloud arguments.786 */787 $tags_sorted = apply_filters( 'tag_cloud_sort', $tags, $args );788 if ( empty( $tags_sorted ) ) {789 return $return;790 }791 792 if ( $tags_sorted !== $tags ) {793 $tags = $tags_sorted;794 unset( $tags_sorted );795 } else {796 if ( 'RAND' === $args['order'] ) {797 shuffle( $tags );798 } else {799 // SQL cannot save you; this is a second (potentially different) sort on a subset of data.800 if ( 'name' === $args['orderby'] ) {801 uasort( $tags, '_wp_object_name_sort_cb' );802 } else {803 uasort( $tags, '_wp_object_count_sort_cb' );804 }805 806 if ( 'DESC' === $args['order'] ) {807 $tags = array_reverse( $tags, true );808 }809 }810 }811 812 if ( $args['number'] > 0 )813 $tags = array_slice( $tags, 0, $args['number'] );814 815 $counts = array();816 $real_counts = array(); // For the alt tag817 foreach ( (array) $tags as $key => $tag ) {818 $real_counts[ $key ] = $tag->count;819 $counts[ $key ] = call_user_func( $args['topic_count_scale_callback'], $tag->count );820 }821 822 $min_count = min( $counts );823 $spread = max( $counts ) - $min_count;824 if ( $spread <= 0 )825 $spread = 1;826 $font_spread = $args['largest'] - $args['smallest'];827 if ( $font_spread < 0 )828 $font_spread = 1;829 $font_step = $font_spread / $spread;830 831 // Assemble the data that will be used to generate the tag cloud markup.832 $tags_data = array();833 foreach ( $tags as $key => $tag ) {834 $tag_id = isset( $tag->id ) ? $tag->id : $key;835 836 $count = $counts[ $key ];837 $real_count = $real_counts[ $key ];838 839 if ( $translate_nooped_plural ) {840 $title = sprintf( translate_nooped_plural( $translate_nooped_plural, $real_count ), number_format_i18n( $real_count ) );841 } else {842 $title = call_user_func( $args['topic_count_text_callback'], $real_count, $tag, $args );843 }844 845 $tags_data[] = array(846 'id' => $tag_id,847 'url' => '#' != $tag->link ? $tag->link : '#',848 'name' => $tag->name,849 'title' => $title,850 'slug' => $tag->slug,851 'real_count' => $real_count,852 'class' => 'tag-link-' . $tag_id,853 'font_size' => $args['smallest'] + ( $count - $min_count ) * $font_step,854 );855 }856 857 /**858 * Filter the data used to generate the tag cloud.859 *860 * @since 4.3.0861 *862 * @param array $tags_data An array of term data for term used to generate the tag cloud.863 */864 $tags_data = apply_filters( 'wp_generate_tag_cloud_data', $tags_data );865 866 $a = array();867 868 // generate the output links array869 foreach ( $tags_data as $key => $tag_data ) {870 $a[] = "<a href='" . esc_url( $tag_data['url'] ) . "' class='" . esc_attr( $tag_data['class'] ) . "' title='" . esc_attr( $tag_data['title'] ) . "' style='font-size: " . esc_attr( str_replace( ',', '.', $tag_data['font_size'] ) . $args['unit'] ) . ";'>" . esc_html( $tag_data['name'] ) . "</a>";871 }872 873 switch ( $args['format'] ) {874 case 'array' :875 $return =& $a;876 break;877 case 'list' :878 $return = "<ul class='wp-tag-cloud'>\n\t<li>";879 $return .= join( "</li>\n\t<li>", $a );880 $return .= "</li>\n</ul>\n";881 break;882 default :883 $return = join( $args['separator'], $a );884 break;885 }886 887 if ( $args['filter'] ) {888 /**889 * Filter the generated output of a tag cloud.890 *891 * The filter is only evaluated if a true value is passed892 * to the $filter argument in wp_generate_tag_cloud().893 *894 * @since 2.3.0895 *896 * @see wp_generate_tag_cloud()897 *898 * @param array|string $return String containing the generated HTML tag cloud output899 * or an array of tag links if the 'format' argument900 * equals 'array'.901 * @param array $tags An array of terms used in the tag cloud.902 * @param array $args An array of wp_generate_tag_cloud() arguments.903 */904 return apply_filters( 'wp_generate_tag_cloud', $return, $tags, $args );905 }906 907 else908 return $return;909 }910 911 /**912 * Callback for comparing objects based on name913 *914 * @since 3.1.0915 * @access private916 * @return int917 */918 function _wp_object_name_sort_cb( $a, $b ) {919 return strnatcasecmp( $a->name, $b->name );920 }921 922 /**923 * Callback for comparing objects based on count924 *925 * @since 3.1.0926 * @access private927 * @return bool928 */929 function _wp_object_count_sort_cb( $a, $b ) {930 return ( $a->count > $b->count );931 }932 933 //934 // Helper functions935 //936 937 /**938 * Retrieve HTML list content for category list.939 *940 * @uses Walker_Category to create HTML list content.941 * @since 2.1.0942 * @see Walker_Category::walk() for parameters and return description.943 * @return string944 */945 function walk_category_tree() {946 $args = func_get_args();947 // the user's options are the third parameter948 if ( empty( $args[2]['walker'] ) || ! ( $args[2]['walker'] instanceof Walker ) ) {949 $walker = new Walker_Category;950 } else {951 $walker = $args[2]['walker'];952 }953 return call_user_func_array( array( $walker, 'walk' ), $args );954 }955 956 /**957 * Retrieve HTML dropdown (select) content for category list.958 *959 * @uses Walker_CategoryDropdown to create HTML dropdown content.960 * @since 2.1.0961 * @see Walker_CategoryDropdown::walk() for parameters and return description.962 * @return string963 */964 function walk_category_dropdown_tree() {965 $args = func_get_args();966 // the user's options are the third parameter967 if ( empty( $args[2]['walker'] ) || ! ( $args[2]['walker'] instanceof Walker ) ) {968 $walker = new Walker_CategoryDropdown;969 } else {970 $walker = $args[2]['walker'];971 }972 return call_user_func_array( array( $walker, 'walk' ), $args );973 }974 975 /**976 * Create HTML list of categories.977 *978 * @package WordPress979 * @since 2.1.0980 * @uses Walker981 */982 class Walker_Category extends Walker {983 /**984 * What the class handles.985 *986 * @see Walker::$tree_type987 * @since 2.1.0988 * @var string989 */990 public $tree_type = 'category';991 992 /**993 * Database fields to use.994 *995 * @see Walker::$db_fields996 * @since 2.1.0997 * @todo Decouple this998 * @var array999 */1000 public $db_fields = array ('parent' => 'parent', 'id' => 'term_id');1001 1002 /**1003 * Starts the list before the elements are added.1004 *1005 * @see Walker::start_lvl()1006 *1007 * @since 2.1.01008 *1009 * @param string $output Passed by reference. Used to append additional content.1010 * @param int $depth Depth of category. Used for tab indentation.1011 * @param array $args An array of arguments. Will only append content if style argument value is 'list'.1012 * @see wp_list_categories()1013 */1014 public function start_lvl( &$output, $depth = 0, $args = array() ) {1015 if ( 'list' != $args['style'] )1016 return;1017 1018 $indent = str_repeat("\t", $depth);1019 $output .= "$indent<ul class='children'>\n";1020 }1021 1022 /**1023 * Ends the list of after the elements are added.1024 *1025 * @see Walker::end_lvl()1026 *1027 * @since 2.1.01028 *1029 * @param string $output Passed by reference. Used to append additional content.1030 * @param int $depth Depth of category. Used for tab indentation.1031 * @param array $args An array of arguments. Will only append content if style argument value is 'list'.1032 * @wsee wp_list_categories()1033 */1034 public function end_lvl( &$output, $depth = 0, $args = array() ) {1035 if ( 'list' != $args['style'] )1036 return;1037 1038 $indent = str_repeat("\t", $depth);1039 $output .= "$indent</ul>\n";1040 }1041 1042 /**1043 * Start the element output.1044 *1045 * @see Walker::start_el()1046 *1047 * @since 2.1.01048 *1049 * @param string $output Passed by reference. Used to append additional content.1050 * @param object $category Category data object.1051 * @param int $depth Depth of category in reference to parents. Default 0.1052 * @param array $args An array of arguments. @see wp_list_categories()1053 * @param int $id ID of the current category.1054 */1055 public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {1056 /** This filter is documented in wp-includes/category-template.php */1057 $cat_name = apply_filters(1058 'list_cats',1059 esc_attr( $category->name ),1060 $category1061 );1062 1063 // Don't generate an element if the category name is empty.1064 if ( ! $cat_name ) {1065 return;1066 }1067 1068 $link = '<a href="' . esc_url( get_term_link( $category ) ) . '" ';1069 if ( $args['use_desc_for_title'] && ! empty( $category->description ) ) {1070 /**1071 * Filter the category description for display.1072 *1073 * @since 1.2.01074 *1075 * @param string $description Category description.1076 * @param object $category Category object.1077 */1078 $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';1079 }1080 1081 $link .= '>';1082 $link .= $cat_name . '</a>';1083 1084 if ( ! empty( $args['feed_image'] ) || ! empty( $args['feed'] ) ) {1085 $link .= ' ';1086 1087 if ( empty( $args['feed_image'] ) ) {1088 $link .= '(';1089 }1090 1091 $link .= '<a href="' . esc_url( get_term_feed_link( $category->term_id, $category->taxonomy, $args['feed_type'] ) ) . '"';1092 1093 if ( empty( $args['feed'] ) ) {1094 $alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';1095 } else {1096 $alt = ' alt="' . $args['feed'] . '"';1097 $name = $args['feed'];1098 $link .= empty( $args['title'] ) ? '' : $args['title'];1099 }1100 1101 $link .= '>';1102 1103 if ( empty( $args['feed_image'] ) ) {1104 $link .= $name;1105 } else {1106 $link .= "<img src='" . $args['feed_image'] . "'$alt" . ' />';1107 }1108 $link .= '</a>';1109 1110 if ( empty( $args['feed_image'] ) ) {1111 $link .= ')';1112 }1113 }1114 1115 if ( ! empty( $args['show_count'] ) ) {1116 $link .= ' (' . number_format_i18n( $category->count ) . ')';1117 }1118 if ( 'list' == $args['style'] ) {1119 $output .= "\t<li";1120 $css_classes = array(1121 'cat-item',1122 'cat-item-' . $category->term_id,1123 );1124 1125 if ( ! empty( $args['current_category'] ) ) {1126 // 'current_category' can be an array, so we use `get_terms()`.1127 $_current_terms = get_terms( $category->taxonomy, array(1128 'include' => $args['current_category'],1129 'hide_empty' => false,1130 ) );1131 1132 foreach ( $_current_terms as $_current_term ) {1133 if ( $category->term_id == $_current_term->term_id ) {1134 $css_classes[] = 'current-cat';1135 } elseif ( $category->term_id == $_current_term->parent ) {1136 $css_classes[] = 'current-cat-parent';1137 }1138 }1139 }1140 1141 /**1142 * Filter the list of CSS classes to include with each category in the list.1143 *1144 * @since 4.2.01145 *1146 * @see wp_list_categories()1147 *1148 * @param array $css_classes An array of CSS classes to be applied to each list item.1149 * @param object $category Category data object.1150 * @param int $depth Depth of page, used for padding.1151 * @param array $args An array of wp_list_categories() arguments.1152 */1153 $css_classes = implode( ' ', apply_filters( 'category_css_class', $css_classes, $category, $depth, $args ) );1154 1155 $output .= ' class="' . $css_classes . '"';1156 $output .= ">$link\n";1157 } else {1158 $output .= "\t$link<br />\n";1159 }1160 }1161 1162 /**1163 * Ends the element output, if needed.1164 *1165 * @see Walker::end_el()1166 *1167 * @since 2.1.01168 *1169 * @param string $output Passed by reference. Used to append additional content.1170 * @param object $page Not used.1171 * @param int $depth Depth of category. Not used.1172 * @param array $args An array of arguments. Only uses 'list' for whether should append to output. @see wp_list_categories()1173 */1174 public function end_el( &$output, $page, $depth = 0, $args = array() ) {1175 if ( 'list' != $args['style'] )1176 return;1177 1178 $output .= "</li>\n";1179 }1180 1181 }1182 8 1183 9 /** … … 1240 66 } 1241 67 } 1242 1243 //1244 // Tags1245 //1246 1247 /**1248 * Retrieve the link to the tag.1249 *1250 * @since 2.3.01251 * @see get_term_link()1252 *1253 * @param int|object $tag Tag ID or object.1254 * @return string Link on success, empty string if tag does not exist.1255 */1256 function get_tag_link( $tag ) {1257 if ( ! is_object( $tag ) )1258 $tag = (int) $tag;1259 1260 $tag = get_term_link( $tag, 'post_tag' );1261 1262 if ( is_wp_error( $tag ) )1263 return '';1264 1265 return $tag;1266 }1267 1268 /**1269 * Retrieve the tags for a post.1270 *1271 * @since 2.3.01272 *1273 * @param int $id Post ID.1274 * @return array|false|WP_Error Array of tag objects on success, false on failure.1275 */1276 function get_the_tags( $id = 0 ) {1277 1278 /**1279 * Filter the array of tags for the given post.1280 *1281 * @since 2.3.01282 *1283 * @see get_the_terms()1284 *1285 * @param array $terms An array of tags for the given post.1286 */1287 return apply_filters( 'get_the_tags', get_the_terms( $id, 'post_tag' ) );1288 }1289 1290 /**1291 * Retrieve the tags for a post formatted as a string.1292 *1293 * @since 2.3.01294 *1295 * @param string $before Optional. Before tags.1296 * @param string $sep Optional. Between tags.1297 * @param string $after Optional. After tags.1298 * @param int $id Optional. Post ID. Defaults to the current post.1299 * @return string|false|WP_Error A list of tags on success, false if there are no terms, WP_Error on failure.1300 */1301 function get_the_tag_list( $before = '', $sep = '', $after = '', $id = 0 ) {1302 1303 /**1304 * Filter the tags list for a given post.1305 *1306 * @since 2.3.01307 *1308 * @param string $tag_list List of tags.1309 * @param string $before String to use before tags.1310 * @param string $sep String to use between the tags.1311 * @param string $after String to use after tags.1312 * @param int $id Post ID.1313 */1314 return apply_filters( 'the_tags', get_the_term_list( $id, 'post_tag', $before, $sep, $after ), $before, $sep, $after, $id );1315 }1316 1317 /**1318 * Retrieve the tags for a post.1319 *1320 * @since 2.3.01321 *1322 * @param string $before Optional. Before list.1323 * @param string $sep Optional. Separate items using this.1324 * @param string $after Optional. After list.1325 */1326 function the_tags( $before = null, $sep = ', ', $after = '' ) {1327 if ( null === $before )1328 $before = __('Tags: ');1329 echo get_the_tag_list($before, $sep, $after);1330 }1331 1332 /**1333 * Retrieve tag description.1334 *1335 * @since 2.8.01336 *1337 * @param int $tag Optional. Tag ID. Will use global tag ID by default.1338 * @return string Tag description, available.1339 */1340 function tag_description( $tag = 0 ) {1341 return term_description( $tag );1342 }1343 1344 /**1345 * Retrieve term description.1346 *1347 * @since 2.8.01348 *1349 * @param int $term Optional. Term ID. Will use global term ID by default.1350 * @param string $taxonomy Optional taxonomy name. Defaults to 'post_tag'.1351 * @return string Term description, available.1352 */1353 function term_description( $term = 0, $taxonomy = 'post_tag' ) {1354 if ( ! $term && ( is_tax() || is_tag() || is_category() ) ) {1355 $term = get_queried_object();1356 if ( $term ) {1357 $taxonomy = $term->taxonomy;1358 $term = $term->term_id;1359 }1360 }1361 $description = get_term_field( 'description', $term, $taxonomy );1362 return is_wp_error( $description ) ? '' : $description;1363 }1364 1365 /**1366 * Retrieve the terms of the taxonomy that are attached to the post.1367 *1368 * @since 2.5.01369 *1370 * @param int|object $post Post ID or object.1371 * @param string $taxonomy Taxonomy name.1372 * @return array|false|WP_Error Array of term objects on success, false if there are no terms1373 * or the post does not exist, WP_Error on failure.1374 */1375 function get_the_terms( $post, $taxonomy ) {1376 if ( ! $post = get_post( $post ) )1377 return false;1378 1379 $terms = get_object_term_cache( $post->ID, $taxonomy );1380 if ( false === $terms ) {1381 $terms = wp_get_object_terms( $post->ID, $taxonomy );1382 wp_cache_add($post->ID, $terms, $taxonomy . '_relationships');1383 }1384 1385 /**1386 * Filter the list of terms attached to the given post.1387 *1388 * @since 3.1.01389 *1390 * @param array|WP_Error $terms List of attached terms, or WP_Error on failure.1391 * @param int $post_id Post ID.1392 * @param string $taxonomy Name of the taxonomy.1393 */1394 $terms = apply_filters( 'get_the_terms', $terms, $post->ID, $taxonomy );1395 1396 if ( empty( $terms ) )1397 return false;1398 1399 return $terms;1400 }1401 1402 /**1403 * Retrieve a post's terms as a list with specified format.1404 *1405 * @since 2.5.01406 *1407 * @param int $id Post ID.1408 * @param string $taxonomy Taxonomy name.1409 * @param string $before Optional. Before list.1410 * @param string $sep Optional. Separate items using this.1411 * @param string $after Optional. After list.1412 * @return string|false|WP_Error A list of terms on success, false if there are no terms, WP_Error on failure.1413 */1414 function get_the_term_list( $id, $taxonomy, $before = '', $sep = '', $after = '' ) {1415 $terms = get_the_terms( $id, $taxonomy );1416 1417 if ( is_wp_error( $terms ) )1418 return $terms;1419 1420 if ( empty( $terms ) )1421 return false;1422 1423 $links = array();1424 1425 foreach ( $terms as $term ) {1426 $link = get_term_link( $term, $taxonomy );1427 if ( is_wp_error( $link ) ) {1428 return $link;1429 }1430 $links[] = '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a>';1431 }1432 1433 /**1434 * Filter the term links for a given taxonomy.1435 *1436 * The dynamic portion of the filter name, `$taxonomy`, refers1437 * to the taxonomy slug.1438 *1439 * @since 2.5.01440 *1441 * @param array $links An array of term links.1442 */1443 $term_links = apply_filters( "term_links-$taxonomy", $links );1444 1445 return $before . join( $sep, $term_links ) . $after;1446 }1447 1448 /**1449 * Display the terms in a list.1450 *1451 * @since 2.5.01452 *1453 * @param int $id Post ID.1454 * @param string $taxonomy Taxonomy name.1455 * @param string $before Optional. Before list.1456 * @param string $sep Optional. Separate items using this.1457 * @param string $after Optional. After list.1458 * @return false|void False on WordPress error.1459 */1460 function the_terms( $id, $taxonomy, $before = '', $sep = ', ', $after = '' ) {1461 $term_list = get_the_term_list( $id, $taxonomy, $before, $sep, $after );1462 1463 if ( is_wp_error( $term_list ) )1464 return false;1465 1466 /**1467 * Filter the list of terms to display.1468 *1469 * @since 2.9.01470 *1471 * @param array $term_list List of terms to display.1472 * @param string $taxonomy The taxonomy name.1473 * @param string $before String to use before the terms.1474 * @param string $sep String to use between the terms.1475 * @param string $after String to use after the terms.1476 */1477 echo apply_filters( 'the_terms', $term_list, $taxonomy, $before, $sep, $after );1478 }1479 1480 /**1481 * Check if the current post has any of given category.1482 *1483 * @since 3.1.01484 *1485 * @param string|int|array $category Optional. The category name/term_id/slug or array of them to check for.1486 * @param int|object $post Optional. Post to check instead of the current post.1487 * @return bool True if the current post has any of the given categories (or any category, if no category specified).1488 */1489 function has_category( $category = '', $post = null ) {1490 return has_term( $category, 'category', $post );1491 }1492 1493 /**1494 * Check if the current post has any of given tags.1495 *1496 * The given tags are checked against the post's tags' term_ids, names and slugs.1497 * Tags given as integers will only be checked against the post's tags' term_ids.1498 * If no tags are given, determines if post has any tags.1499 *1500 * Prior to v2.7 of WordPress, tags given as integers would also be checked against the post's tags' names and slugs (in addition to term_ids)1501 * Prior to v2.7, this function could only be used in the WordPress Loop.1502 * As of 2.7, the function can be used anywhere if it is provided a post ID or post object.1503 *1504 * @since 2.6.01505 *1506 * @param string|int|array $tag Optional. The tag name/term_id/slug or array of them to check for.1507 * @param int|object $post Optional. Post to check instead of the current post. (since 2.7.0)1508 * @return bool True if the current post has any of the given tags (or any tag, if no tag specified).1509 */1510 function has_tag( $tag = '', $post = null ) {1511 return has_term( $tag, 'post_tag', $post );1512 }1513 1514 /**1515 * Check if the current post has any of given terms.1516 *1517 * The given terms are checked against the post's terms' term_ids, names and slugs.1518 * Terms given as integers will only be checked against the post's terms' term_ids.1519 * If no terms are given, determines if post has any terms.1520 *1521 * @since 3.1.01522 *1523 * @param string|int|array $term Optional. The term name/term_id/slug or array of them to check for.1524 * @param string $taxonomy Taxonomy name1525 * @param int|object $post Optional. Post to check instead of the current post.1526 * @return bool True if the current post has any of the given tags (or any tag, if no tag specified).1527 */1528 function has_term( $term = '', $taxonomy = '', $post = null ) {1529 $post = get_post($post);1530 1531 if ( !$post )1532 return false;1533 1534 $r = is_object_in_term( $post->ID, $taxonomy, $term );1535 if ( is_wp_error( $r ) )1536 return false;1537 1538 return $r;1539 } -
trunk/src/wp-includes/class-walker-category.php
r34109 r34110 1 1 <?php 2 2 /** 3 * Category Template Tags and API.3 * Category API: Walker_Category class 4 4 * 5 5 * @package WordPress 6 6 * @subpackage Template 7 7 */ 8 9 /**10 * Retrieve category link URL.11 *12 * @since 1.0.013 * @see get_term_link()14 *15 * @param int|object $category Category ID or object.16 * @return string Link on success, empty string if category does not exist.17 */18 function get_category_link( $category ) {19 if ( ! is_object( $category ) )20 $category = (int) $category;21 22 $category = get_term_link( $category, 'category' );23 24 if ( is_wp_error( $category ) )25 return '';26 27 return $category;28 }29 30 /**31 * Retrieve category parents with separator.32 *33 * @since 1.2.034 *35 * @param int $id Category ID.36 * @param bool $link Optional, default is false. Whether to format with link.37 * @param string $separator Optional, default is '/'. How to separate categories.38 * @param bool $nicename Optional, default is false. Whether to use nice name for display.39 * @param array $visited Optional. Already linked to categories to prevent duplicates.40 * @return string|WP_Error A list of category parents on success, WP_Error on failure.41 */42 function get_category_parents( $id, $link = false, $separator = '/', $nicename = false, $visited = array() ) {43 $chain = '';44 $parent = get_term( $id, 'category' );45 if ( is_wp_error( $parent ) )46 return $parent;47 48 if ( $nicename )49 $name = $parent->slug;50 else51 $name = $parent->name;52 53 if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) {54 $visited[] = $parent->parent;55 $chain .= get_category_parents( $parent->parent, $link, $separator, $nicename, $visited );56 }57 58 if ( $link )59 $chain .= '<a href="' . esc_url( get_category_link( $parent->term_id ) ) . '">'.$name.'</a>' . $separator;60 else61 $chain .= $name.$separator;62 return $chain;63 }64 65 /**66 * Retrieve post categories.67 *68 * This tag may be used outside The Loop by passing a post id as the parameter.69 *70 * Note: This function only returns results from the default "category" taxonomy.71 * For custom taxonomies use get_the_terms().72 *73 * @since 0.7174 *75 * @param int $id Optional, default to current post ID. The post ID.76 * @return array Array of objects, one for each category assigned to the post.77 */78 function get_the_category( $id = false ) {79 $categories = get_the_terms( $id, 'category' );80 if ( ! $categories || is_wp_error( $categories ) )81 $categories = array();82 83 $categories = array_values( $categories );84 85 foreach ( array_keys( $categories ) as $key ) {86 _make_cat_compat( $categories[$key] );87 }88 89 /**90 * Filter the array of categories to return for a post.91 *92 * @since 3.1.093 *94 * @param array $categories An array of categories to return for the post.95 */96 return apply_filters( 'get_the_categories', $categories );97 }98 99 /**100 * Sort categories by name.101 *102 * Used by usort() as a callback, should not be used directly. Can actually be103 * used to sort any term object.104 *105 * @since 2.3.0106 * @access private107 *108 * @param object $a109 * @param object $b110 * @return int111 */112 function _usort_terms_by_name( $a, $b ) {113 return strcmp( $a->name, $b->name );114 }115 116 /**117 * Sort categories by ID.118 *119 * Used by usort() as a callback, should not be used directly. Can actually be120 * used to sort any term object.121 *122 * @since 2.3.0123 * @access private124 *125 * @param object $a126 * @param object $b127 * @return int128 */129 function _usort_terms_by_ID( $a, $b ) {130 if ( $a->term_id > $b->term_id )131 return 1;132 elseif ( $a->term_id < $b->term_id )133 return -1;134 else135 return 0;136 }137 138 /**139 * Retrieve category name based on category ID.140 *141 * @since 0.71142 *143 * @param int $cat_ID Category ID.144 * @return string|WP_Error Category name on success, WP_Error on failure.145 */146 function get_the_category_by_ID( $cat_ID ) {147 $cat_ID = (int) $cat_ID;148 $category = get_term( $cat_ID, 'category' );149 150 if ( is_wp_error( $category ) )151 return $category;152 153 return ( $category ) ? $category->name : '';154 }155 156 /**157 * Retrieve category list in either HTML list or custom format.158 *159 * @since 1.5.1160 *161 * @global WP_Rewrite $wp_rewrite162 *163 * @param string $separator Optional, default is empty string. Separator for between the categories.164 * @param string $parents Optional. How to display the parents.165 * @param int $post_id Optional. Post ID to retrieve categories.166 * @return string167 */168 function get_the_category_list( $separator = '', $parents='', $post_id = false ) {169 global $wp_rewrite;170 if ( ! is_object_in_taxonomy( get_post_type( $post_id ), 'category' ) ) {171 /** This filter is documented in wp-includes/category-template.php */172 return apply_filters( 'the_category', '', $separator, $parents );173 }174 175 $categories = get_the_category( $post_id );176 if ( empty( $categories ) ) {177 /** This filter is documented in wp-includes/category-template.php */178 return apply_filters( 'the_category', __( 'Uncategorized' ), $separator, $parents );179 }180 181 $rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';182 183 $thelist = '';184 if ( '' == $separator ) {185 $thelist .= '<ul class="post-categories">';186 foreach ( $categories as $category ) {187 $thelist .= "\n\t<li>";188 switch ( strtolower( $parents ) ) {189 case 'multiple':190 if ( $category->parent )191 $thelist .= get_category_parents( $category->parent, true, $separator );192 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';193 break;194 case 'single':195 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';196 if ( $category->parent )197 $thelist .= get_category_parents( $category->parent, false, $separator );198 $thelist .= $category->name.'</a></li>';199 break;200 case '':201 default:202 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';203 }204 }205 $thelist .= '</ul>';206 } else {207 $i = 0;208 foreach ( $categories as $category ) {209 if ( 0 < $i )210 $thelist .= $separator;211 switch ( strtolower( $parents ) ) {212 case 'multiple':213 if ( $category->parent )214 $thelist .= get_category_parents( $category->parent, true, $separator );215 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a>';216 break;217 case 'single':218 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';219 if ( $category->parent )220 $thelist .= get_category_parents( $category->parent, false, $separator );221 $thelist .= "$category->name</a>";222 break;223 case '':224 default:225 $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a>';226 }227 ++$i;228 }229 }230 231 /**232 * Filter the category or list of categories.233 *234 * @since 1.2.0235 *236 * @param array $thelist List of categories for the current post.237 * @param string $separator Separator used between the categories.238 * @param string $parents How to display the category parents. Accepts 'multiple',239 * 'single', or empty.240 */241 return apply_filters( 'the_category', $thelist, $separator, $parents );242 }243 244 /**245 * Check if the current post in within any of the given categories.246 *247 * The given categories are checked against the post's categories' term_ids, names and slugs.248 * Categories given as integers will only be checked against the post's categories' term_ids.249 *250 * Prior to v2.5 of WordPress, category names were not supported.251 * Prior to v2.7, category slugs were not supported.252 * Prior to v2.7, only one category could be compared: in_category( $single_category ).253 * Prior to v2.7, this function could only be used in the WordPress Loop.254 * As of 2.7, the function can be used anywhere if it is provided a post ID or post object.255 *256 * @since 1.2.0257 *258 * @param int|string|array $category Category ID, name or slug, or array of said.259 * @param int|object $post Optional. Post to check instead of the current post. (since 2.7.0)260 * @return bool True if the current post is in any of the given categories.261 */262 function in_category( $category, $post = null ) {263 if ( empty( $category ) )264 return false;265 266 return has_category( $category, $post );267 }268 269 /**270 * Display the category list for the post.271 *272 * @since 0.71273 *274 * @param string $separator Optional, default is empty string. Separator for between the categories.275 * @param string $parents Optional. How to display the parents.276 * @param int $post_id Optional. Post ID to retrieve categories.277 */278 function the_category( $separator = '', $parents='', $post_id = false ) {279 echo get_the_category_list( $separator, $parents, $post_id );280 }281 282 /**283 * Retrieve category description.284 *285 * @since 1.0.0286 *287 * @param int $category Optional. Category ID. Will use global category ID by default.288 * @return string Category description, available.289 */290 function category_description( $category = 0 ) {291 return term_description( $category, 'category' );292 }293 294 /**295 * Display or retrieve the HTML dropdown list of categories.296 *297 * The 'hierarchical' argument, which is disabled by default, will override the298 * depth argument, unless it is true. When the argument is false, it will299 * display all of the categories. When it is enabled it will use the value in300 * the 'depth' argument.301 *302 * @since 2.1.0303 * @since 4.2.0 Introduced the `value_field` argument.304 *305 * @param string|array $args {306 * Optional. Array or string of arguments to generate a categories drop-down element.307 *308 * @type string $show_option_all Text to display for showing all categories. Default empty.309 * @type string $show_option_none Text to display for showing no categories. Default empty.310 * @type string $option_none_value Value to use when no category is selected. Default empty.311 * @type string $orderby Which column to use for ordering categories. See get_terms() for a list312 * of accepted values. Default 'id' (term_id).313 * @type string $order Whether to order terms in ascending or descending order. Accepts 'ASC'314 * or 'DESC'. Default 'ASC'.315 * @type bool $pad_counts See get_terms() for an argument description. Default false.316 * @type bool|int $show_count Whether to include post counts. Accepts 0, 1, or their bool equivalents.317 * Default 0.318 * @type bool|int $hide_empty Whether to hide categories that don't have any posts. Accepts 0, 1, or319 * their bool equivalents. Default 1.320 * @type int $child_of Term ID to retrieve child terms of. See get_terms(). Default 0.321 * @type array|string $exclude Array or comma/space-separated string of term ids to exclude.322 * If `$include` is non-empty, `$exclude` is ignored. Default empty array.323 * @type bool|int $echo Whether to echo or return the generated markup. Accepts 0, 1, or their324 * bool equivalents. Default 1.325 * @type bool|int $hierarchical Whether to traverse the taxonomy hierarchy. Accepts 0, 1, or their bool326 * equivalents. Default 0.327 * @type int $depth Maximum depth. Default 0.328 * @type int $tab_index Tab index for the select element. Default 0 (no tabindex).329 * @type string $name Value for the 'name' attribute of the select element. Default 'cat'.330 * @type string $id Value for the 'id' attribute of the select element. Defaults to the value331 * of `$name`.332 * @type string $class Value for the 'class' attribute of the select element. Default 'postform'.333 * @type int|string $selected Value of the option that should be selected. Default 0.334 * @type string $value_field Term field that should be used to populate the 'value' attribute335 * of the option elements. Accepts any valid term field: 'term_id', 'name',336 * 'slug', 'term_group', 'term_taxonomy_id', 'taxonomy', 'description',337 * 'parent', 'count'. Default 'term_id'.338 * @type string $taxonomy Name of the category to retrieve. Default 'category'.339 * @type bool $hide_if_empty True to skip generating markup if no categories are found.340 * Default false (create select element even if no categories are found).341 * }342 * @return string HTML content only if 'echo' argument is 0.343 */344 function wp_dropdown_categories( $args = '' ) {345 $defaults = array(346 'show_option_all' => '', 'show_option_none' => '',347 'orderby' => 'id', 'order' => 'ASC',348 'show_count' => 0,349 'hide_empty' => 1, 'child_of' => 0,350 'exclude' => '', 'echo' => 1,351 'selected' => 0, 'hierarchical' => 0,352 'name' => 'cat', 'id' => '',353 'class' => 'postform', 'depth' => 0,354 'tab_index' => 0, 'taxonomy' => 'category',355 'hide_if_empty' => false, 'option_none_value' => -1,356 'value_field' => 'term_id',357 );358 359 $defaults['selected'] = ( is_category() ) ? get_query_var( 'cat' ) : 0;360 361 // Back compat.362 if ( isset( $args['type'] ) && 'link' == $args['type'] ) {363 _deprecated_argument( __FUNCTION__, '3.0', '' );364 $args['taxonomy'] = 'link_category';365 }366 367 $r = wp_parse_args( $args, $defaults );368 $option_none_value = $r['option_none_value'];369 370 if ( ! isset( $r['pad_counts'] ) && $r['show_count'] && $r['hierarchical'] ) {371 $r['pad_counts'] = true;372 }373 374 $tab_index = $r['tab_index'];375 376 $tab_index_attribute = '';377 if ( (int) $tab_index > 0 ) {378 $tab_index_attribute = " tabindex=\"$tab_index\"";379 }380 381 // Avoid clashes with the 'name' param of get_terms().382 $get_terms_args = $r;383 unset( $get_terms_args['name'] );384 $categories = get_terms( $r['taxonomy'], $get_terms_args );385 386 $name = esc_attr( $r['name'] );387 $class = esc_attr( $r['class'] );388 $id = $r['id'] ? esc_attr( $r['id'] ) : $name;389 390 if ( ! $r['hide_if_empty'] || ! empty( $categories ) ) {391 $output = "<select name='$name' id='$id' class='$class' $tab_index_attribute>\n";392 } else {393 $output = '';394 }395 if ( empty( $categories ) && ! $r['hide_if_empty'] && ! empty( $r['show_option_none'] ) ) {396 397 /**398 * Filter a taxonomy drop-down display element.399 *400 * A variety of taxonomy drop-down display elements can be modified401 * just prior to display via this filter. Filterable arguments include402 * 'show_option_none', 'show_option_all', and various forms of the403 * term name.404 *405 * @since 1.2.0406 *407 * @see wp_dropdown_categories()408 *409 * @param string $element Taxonomy element to list.410 */411 $show_option_none = apply_filters( 'list_cats', $r['show_option_none'] );412 $output .= "\t<option value='" . esc_attr( $option_none_value ) . "' selected='selected'>$show_option_none</option>\n";413 }414 415 if ( ! empty( $categories ) ) {416 417 if ( $r['show_option_all'] ) {418 419 /** This filter is documented in wp-includes/category-template.php */420 $show_option_all = apply_filters( 'list_cats', $r['show_option_all'] );421 $selected = ( '0' === strval($r['selected']) ) ? " selected='selected'" : '';422 $output .= "\t<option value='0'$selected>$show_option_all</option>\n";423 }424 425 if ( $r['show_option_none'] ) {426 427 /** This filter is documented in wp-includes/category-template.php */428 $show_option_none = apply_filters( 'list_cats', $r['show_option_none'] );429 $selected = selected( $option_none_value, $r['selected'], false );430 $output .= "\t<option value='" . esc_attr( $option_none_value ) . "'$selected>$show_option_none</option>\n";431 }432 433 if ( $r['hierarchical'] ) {434 $depth = $r['depth']; // Walk the full depth.435 } else {436 $depth = -1; // Flat.437 }438 $output .= walk_category_dropdown_tree( $categories, $depth, $r );439 }440 441 if ( ! $r['hide_if_empty'] || ! empty( $categories ) ) {442 $output .= "</select>\n";443 }444 /**445 * Filter the taxonomy drop-down output.446 *447 * @since 2.1.0448 *449 * @param string $output HTML output.450 * @param array $r Arguments used to build the drop-down.451 */452 $output = apply_filters( 'wp_dropdown_cats', $output, $r );453 454 if ( $r['echo'] ) {455 echo $output;456 }457 return $output;458 }459 460 /**461 * Display or retrieve the HTML list of categories.462 *463 * @since 2.1.0464 * @since 4.4.0 Introduced the `hide_title_if_empty` argument. The `current_category` argument was modified to465 * optionally accept an array of values.466 *467 * @param string|array $args {468 * Array of optional arguments.469 *470 * @type string $show_option_all Text to display for showing all categories. Default empty string.471 * @type string $show_option_none Text to display for the 'no categories' option.472 * Default 'No categories'.473 * @type string $orderby The column to use for ordering categories. Default 'ID'.474 * @type string $order Which direction to order categories. Accepts 'ASC' or 'DESC'.475 * Default 'ASC'.476 * @type bool|int $show_count Whether to show how many posts are in the category. Default 0.477 * @type bool|int $hide_empty Whether to hide categories that don't have any posts attached to them.478 * Default 1.479 * @type bool|int $use_desc_for_title Whether to use the category description as the title attribute.480 * Default 1.481 * @type string $feed Text to use for the feed link. Default 'Feed for all posts filed482 * under [cat name]'.483 * @type string $feed_type Feed type. Used to build feed link. See {@link get_term_feed_link()}.484 * Default empty string (default feed).485 * @type string $feed_image URL of an image to use for the feed link. Default empty string.486 * @type int $child_of Term ID to retrieve child terms of. See {@link get_terms()}. Default 0.487 * @type array|string $exclude Array or comma/space-separated string of term IDs to exclude.488 * See {@link get_terms()}. Default empty string.489 * @type array|string $exclude_tree Array or comma/space-separated string of term IDs to exclude, along490 * with their descendants. See {@link get_terms()}. Default empty string.491 * @type bool|int $echo True to echo markup, false to return it. Default 1.492 * @type int|array $current_category ID of category, or array of IDs of categories, that should get the493 * 'current-cat' class. Default 0.494 * @type bool $hierarchical Whether to include terms that have non-empty descendants.495 * See {@link get_terms()}. Default true.496 * @type string $title_li Text to use for the list title `<li>` element. Pass an empty string497 * to disable. Default 'Categories'.498 * @type bool $hide_title_if_empty Whether to hide the `$title_li` element if there are no terms in499 * the list. Default false (title will always be shown).500 * @type int $depth Category depth. Used for tab indentation. Default 0.501 * @type string $taxonomy Taxonomy name. Default 'category'.502 * }503 * @return false|string HTML content only if 'echo' argument is 0.504 */505 function wp_list_categories( $args = '' ) {506 $defaults = array(507 'show_option_all' => '', 'show_option_none' => __('No categories'),508 'orderby' => 'name', 'order' => 'ASC',509 'style' => 'list',510 'show_count' => 0, 'hide_empty' => 1,511 'use_desc_for_title' => 1, 'child_of' => 0,512 'feed' => '', 'feed_type' => '',513 'feed_image' => '', 'exclude' => '',514 'exclude_tree' => '', 'current_category' => 0,515 'hierarchical' => true, 'title_li' => __( 'Categories' ),516 'hide_title_if_empty' => false,517 'echo' => 1, 'depth' => 0,518 'taxonomy' => 'category'519 );520 521 $r = wp_parse_args( $args, $defaults );522 523 if ( !isset( $r['pad_counts'] ) && $r['show_count'] && $r['hierarchical'] )524 $r['pad_counts'] = true;525 526 if ( true == $r['hierarchical'] ) {527 $r['exclude_tree'] = $r['exclude'];528 $r['exclude'] = '';529 }530 531 if ( ! isset( $r['class'] ) )532 $r['class'] = ( 'category' == $r['taxonomy'] ) ? 'categories' : $r['taxonomy'];533 534 if ( ! taxonomy_exists( $r['taxonomy'] ) ) {535 return false;536 }537 538 $show_option_all = $r['show_option_all'];539 $show_option_none = $r['show_option_none'];540 541 $categories = get_categories( $r );542 543 $output = '';544 if ( $r['title_li'] && 'list' == $r['style'] && ( ! empty( $categories ) || ! $r['hide_title_if_empty'] ) ) {545 $output = '<li class="' . esc_attr( $r['class'] ) . '">' . $r['title_li'] . '<ul>';546 }547 if ( empty( $categories ) ) {548 if ( ! empty( $show_option_none ) ) {549 if ( 'list' == $r['style'] ) {550 $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';551 } else {552 $output .= $show_option_none;553 }554 }555 } else {556 if ( ! empty( $show_option_all ) ) {557 558 $posts_page = '';559 560 // For taxonomies that belong only to custom post types, point to a valid archive.561 $taxonomy_object = get_taxonomy( $r['taxonomy'] );562 if ( ! in_array( 'post', $taxonomy_object->object_type ) && ! in_array( 'page', $taxonomy_object->object_type ) ) {563 foreach ( $taxonomy_object->object_type as $object_type ) {564 $_object_type = get_post_type_object( $object_type );565 566 // Grab the first one.567 if ( ! empty( $_object_type->has_archive ) ) {568 $posts_page = get_post_type_archive_link( $object_type );569 break;570 }571 }572 }573 574 // Fallback for the 'All' link is the front page.575 if ( ! $posts_page ) {576 $posts_page = 'page' == get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) ? get_permalink( get_option( 'page_for_posts' ) ) : home_url( '/' );577 }578 579 $posts_page = esc_url( $posts_page );580 if ( 'list' == $r['style'] ) {581 $output .= "<li class='cat-item-all'><a href='$posts_page'>$show_option_all</a></li>";582 } else {583 $output .= "<a href='$posts_page'>$show_option_all</a>";584 }585 }586 587 if ( empty( $r['current_category'] ) && ( is_category() || is_tax() || is_tag() ) ) {588 $current_term_object = get_queried_object();589 if ( $current_term_object && $r['taxonomy'] === $current_term_object->taxonomy ) {590 $r['current_category'] = get_queried_object_id();591 }592 }593 594 if ( $r['hierarchical'] ) {595 $depth = $r['depth'];596 } else {597 $depth = -1; // Flat.598 }599 $output .= walk_category_tree( $categories, $depth, $r );600 }601 602 if ( $r['title_li'] && 'list' == $r['style'] )603 $output .= '</ul></li>';604 605 /**606 * Filter the HTML output of a taxonomy list.607 *608 * @since 2.1.0609 *610 * @param string $output HTML output.611 * @param array $args An array of taxonomy-listing arguments.612 */613 $html = apply_filters( 'wp_list_categories', $output, $args );614 615 if ( $r['echo'] ) {616 echo $html;617 } else {618 return $html;619 }620 }621 622 /**623 * Display tag cloud.624 *625 * The text size is set by the 'smallest' and 'largest' arguments, which will626 * use the 'unit' argument value for the CSS text size unit. The 'format'627 * argument can be 'flat' (default), 'list', or 'array'. The flat value for the628 * 'format' argument will separate tags with spaces. The list value for the629 * 'format' argument will format the tags in a UL HTML list. The array value for630 * the 'format' argument will return in PHP array type format.631 *632 * The 'orderby' argument will accept 'name' or 'count' and defaults to 'name'.633 * The 'order' is the direction to sort, defaults to 'ASC' and can be 'DESC'.634 *635 * The 'number' argument is how many tags to return. By default, the limit will636 * be to return the top 45 tags in the tag cloud list.637 *638 * The 'topic_count_text' argument is a nooped plural from _n_noop() to generate the639 * text for the tooltip of the tag link.640 *641 * The 'topic_count_text_callback' argument is a function, which given the count642 * of the posts with that tag returns a text for the tooltip of the tag link.643 *644 * The 'post_type' argument is used only when 'link' is set to 'edit'. It determines the post_type645 * passed to edit.php for the popular tags edit links.646 *647 * The 'exclude' and 'include' arguments are used for the {@link get_tags()}648 * function. Only one should be used, because only one will be used and the649 * other ignored, if they are both set.650 *651 * @since 2.3.0652 *653 * @param array|string|null $args Optional. Override default arguments.654 * @return void|array Generated tag cloud, only if no failures and 'array' is set for the 'format' argument.655 * Otherwise, this function outputs the tag cloud.656 */657 function wp_tag_cloud( $args = '' ) {658 $defaults = array(659 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45,660 'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC',661 'exclude' => '', 'include' => '', 'link' => 'view', 'taxonomy' => 'post_tag', 'post_type' => '', 'echo' => true662 );663 $args = wp_parse_args( $args, $defaults );664 665 $tags = get_terms( $args['taxonomy'], array_merge( $args, array( 'orderby' => 'count', 'order' => 'DESC' ) ) ); // Always query top tags666 667 if ( empty( $tags ) || is_wp_error( $tags ) )668 return;669 670 foreach ( $tags as $key => $tag ) {671 if ( 'edit' == $args['link'] )672 $link = get_edit_term_link( $tag->term_id, $tag->taxonomy, $args['post_type'] );673 else674 $link = get_term_link( intval($tag->term_id), $tag->taxonomy );675 if ( is_wp_error( $link ) )676 return;677 678 $tags[ $key ]->link = $link;679 $tags[ $key ]->id = $tag->term_id;680 }681 682 $return = wp_generate_tag_cloud( $tags, $args ); // Here's where those top tags get sorted according to $args683 684 /**685 * Filter the tag cloud output.686 *687 * @since 2.3.0688 *689 * @param string $return HTML output of the tag cloud.690 * @param array $args An array of tag cloud arguments.691 */692 $return = apply_filters( 'wp_tag_cloud', $return, $args );693 694 if ( 'array' == $args['format'] || empty($args['echo']) )695 return $return;696 697 echo $return;698 }699 700 /**701 * Default topic count scaling for tag links702 *703 * @param int $count number of posts with that tag704 * @return int scaled count705 */706 function default_topic_count_scale( $count ) {707 return round(log10($count + 1) * 100);708 }709 710 /**711 * Generates a tag cloud (heatmap) from provided data.712 *713 * The text size is set by the 'smallest' and 'largest' arguments, which will714 * use the 'unit' argument value for the CSS text size unit. The 'format'715 * argument can be 'flat' (default), 'list', or 'array'. The flat value for the716 * 'format' argument will separate tags with spaces. The list value for the717 * 'format' argument will format the tags in a UL HTML list. The array value for718 * the 'format' argument will return in PHP array type format.719 *720 * The 'tag_cloud_sort' filter allows you to override the sorting.721 * Passed to the filter: $tags array and $args array, has to return the $tags array722 * after sorting it.723 *724 * The 'orderby' argument will accept 'name' or 'count' and defaults to 'name'.725 * The 'order' is the direction to sort, defaults to 'ASC' and can be 'DESC' or726 * 'RAND'.727 *728 * The 'number' argument is how many tags to return. By default, the limit will729 * be to return the entire tag cloud list.730 *731 * The 'topic_count_text' argument is a nooped plural from _n_noop() to generate the732 * text for the tooltip of the tag link.733 *734 * The 'topic_count_text_callback' argument is a function, which given the count735 * of the posts with that tag returns a text for the tooltip of the tag link.736 *737 * @todo Complete functionality.738 * @since 2.3.0739 *740 * @param array $tags List of tags.741 * @param string|array $args Optional, override default arguments.742 * @return string|array Tag cloud as a string or an array, depending on 'format' argument.743 */744 function wp_generate_tag_cloud( $tags, $args = '' ) {745 $defaults = array(746 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 0,747 'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC',748 'topic_count_text' => null, 'topic_count_text_callback' => null,749 'topic_count_scale_callback' => 'default_topic_count_scale', 'filter' => 1,750 );751 752 $args = wp_parse_args( $args, $defaults );753 754 $return = ( 'array' === $args['format'] ) ? array() : '';755 756 if ( empty( $tags ) ) {757 return $return;758 }759 760 // Juggle topic count tooltips:761 if ( isset( $args['topic_count_text'] ) ) {762 // First look for nooped plural support via topic_count_text.763 $translate_nooped_plural = $args['topic_count_text'];764 } elseif ( ! empty( $args['topic_count_text_callback'] ) ) {765 // Look for the alternative callback style. Ignore the previous default.766 if ( $args['topic_count_text_callback'] === 'default_topic_count_text' ) {767 $translate_nooped_plural = _n_noop( '%s topic', '%s topics' );768 } else {769 $translate_nooped_plural = false;770 }771 } elseif ( isset( $args['single_text'] ) && isset( $args['multiple_text'] ) ) {772 // If no callback exists, look for the old-style single_text and multiple_text arguments.773 $translate_nooped_plural = _n_noop( $args['single_text'], $args['multiple_text'] );774 } else {775 // This is the default for when no callback, plural, or argument is passed in.776 $translate_nooped_plural = _n_noop( '%s topic', '%s topics' );777 }778 779 /**780 * Filter how the items in a tag cloud are sorted.781 *782 * @since 2.8.0783 *784 * @param array $tags Ordered array of terms.785 * @param array $args An array of tag cloud arguments.786 */787 $tags_sorted = apply_filters( 'tag_cloud_sort', $tags, $args );788 if ( empty( $tags_sorted ) ) {789 return $return;790 }791 792 if ( $tags_sorted !== $tags ) {793 $tags = $tags_sorted;794 unset( $tags_sorted );795 } else {796 if ( 'RAND' === $args['order'] ) {797 shuffle( $tags );798 } else {799 // SQL cannot save you; this is a second (potentially different) sort on a subset of data.800 if ( 'name' === $args['orderby'] ) {801 uasort( $tags, '_wp_object_name_sort_cb' );802 } else {803 uasort( $tags, '_wp_object_count_sort_cb' );804 }805 806 if ( 'DESC' === $args['order'] ) {807 $tags = array_reverse( $tags, true );808 }809 }810 }811 812 if ( $args['number'] > 0 )813 $tags = array_slice( $tags, 0, $args['number'] );814 815 $counts = array();816 $real_counts = array(); // For the alt tag817 foreach ( (array) $tags as $key => $tag ) {818 $real_counts[ $key ] = $tag->count;819 $counts[ $key ] = call_user_func( $args['topic_count_scale_callback'], $tag->count );820 }821 822 $min_count = min( $counts );823 $spread = max( $counts ) - $min_count;824 if ( $spread <= 0 )825 $spread = 1;826 $font_spread = $args['largest'] - $args['smallest'];827 if ( $font_spread < 0 )828 $font_spread = 1;829 $font_step = $font_spread / $spread;830 831 // Assemble the data that will be used to generate the tag cloud markup.832 $tags_data = array();833 foreach ( $tags as $key => $tag ) {834 $tag_id = isset( $tag->id ) ? $tag->id : $key;835 836 $count = $counts[ $key ];837 $real_count = $real_counts[ $key ];838 839 if ( $translate_nooped_plural ) {840 $title = sprintf( translate_nooped_plural( $translate_nooped_plural, $real_count ), number_format_i18n( $real_count ) );841 } else {842 $title = call_user_func( $args['topic_count_text_callback'], $real_count, $tag, $args );843 }844 845 $tags_data[] = array(846 'id' => $tag_id,847 'url' => '#' != $tag->link ? $tag->link : '#',848 'name' => $tag->name,849 'title' => $title,850 'slug' => $tag->slug,851 'real_count' => $real_count,852 'class' => 'tag-link-' . $tag_id,853 'font_size' => $args['smallest'] + ( $count - $min_count ) * $font_step,854 );855 }856 857 /**858 * Filter the data used to generate the tag cloud.859 *860 * @since 4.3.0861 *862 * @param array $tags_data An array of term data for term used to generate the tag cloud.863 */864 $tags_data = apply_filters( 'wp_generate_tag_cloud_data', $tags_data );865 866 $a = array();867 868 // generate the output links array869 foreach ( $tags_data as $key => $tag_data ) {870 $a[] = "<a href='" . esc_url( $tag_data['url'] ) . "' class='" . esc_attr( $tag_data['class'] ) . "' title='" . esc_attr( $tag_data['title'] ) . "' style='font-size: " . esc_attr( str_replace( ',', '.', $tag_data['font_size'] ) . $args['unit'] ) . ";'>" . esc_html( $tag_data['name'] ) . "</a>";871 }872 873 switch ( $args['format'] ) {874 case 'array' :875 $return =& $a;876 break;877 case 'list' :878 $return = "<ul class='wp-tag-cloud'>\n\t<li>";879 $return .= join( "</li>\n\t<li>", $a );880 $return .= "</li>\n</ul>\n";881 break;882 default :883 $return = join( $args['separator'], $a );884 break;885 }886 887 if ( $args['filter'] ) {888 /**889 * Filter the generated output of a tag cloud.890 *891 * The filter is only evaluated if a true value is passed892 * to the $filter argument in wp_generate_tag_cloud().893 *894 * @since 2.3.0895 *896 * @see wp_generate_tag_cloud()897 *898 * @param array|string $return String containing the generated HTML tag cloud output899 * or an array of tag links if the 'format' argument900 * equals 'array'.901 * @param array $tags An array of terms used in the tag cloud.902 * @param array $args An array of wp_generate_tag_cloud() arguments.903 */904 return apply_filters( 'wp_generate_tag_cloud', $return, $tags, $args );905 }906 907 else908 return $return;909 }910 911 /**912 * Callback for comparing objects based on name913 *914 * @since 3.1.0915 * @access private916 * @return int917 */918 function _wp_object_name_sort_cb( $a, $b ) {919 return strnatcasecmp( $a->name, $b->name );920 }921 922 /**923 * Callback for comparing objects based on count924 *925 * @since 3.1.0926 * @access private927 * @return bool928 */929 function _wp_object_count_sort_cb( $a, $b ) {930 return ( $a->count > $b->count );931 }932 933 //934 // Helper functions935 //936 937 /**938 * Retrieve HTML list content for category list.939 *940 * @uses Walker_Category to create HTML list content.941 * @since 2.1.0942 * @see Walker_Category::walk() for parameters and return description.943 * @return string944 */945 function walk_category_tree() {946 $args = func_get_args();947 // the user's options are the third parameter948 if ( empty( $args[2]['walker'] ) || ! ( $args[2]['walker'] instanceof Walker ) ) {949 $walker = new Walker_Category;950 } else {951 $walker = $args[2]['walker'];952 }953 return call_user_func_array( array( $walker, 'walk' ), $args );954 }955 956 /**957 * Retrieve HTML dropdown (select) content for category list.958 *959 * @uses Walker_CategoryDropdown to create HTML dropdown content.960 * @since 2.1.0961 * @see Walker_CategoryDropdown::walk() for parameters and return description.962 * @return string963 */964 function walk_category_dropdown_tree() {965 $args = func_get_args();966 // the user's options are the third parameter967 if ( empty( $args[2]['walker'] ) || ! ( $args[2]['walker'] instanceof Walker ) ) {968 $walker = new Walker_CategoryDropdown;969 } else {970 $walker = $args[2]['walker'];971 }972 return call_user_func_array( array( $walker, 'walk' ), $args );973 }974 8 975 9 /** … … 1180 214 1181 215 } 1182 1183 /**1184 * Create HTML dropdown list of Categories.1185 *1186 * @package WordPress1187 * @since 2.1.01188 * @uses Walker1189 */1190 class Walker_CategoryDropdown extends Walker {1191 /**1192 * @see Walker::$tree_type1193 * @since 2.1.01194 * @var string1195 */1196 public $tree_type = 'category';1197 1198 /**1199 * @see Walker::$db_fields1200 * @since 2.1.01201 * @todo Decouple this1202 * @var array1203 */1204 public $db_fields = array ('parent' => 'parent', 'id' => 'term_id');1205 1206 /**1207 * Start the element output.1208 *1209 * @see Walker::start_el()1210 * @since 2.1.01211 *1212 * @param string $output Passed by reference. Used to append additional content.1213 * @param object $category Category data object.1214 * @param int $depth Depth of category. Used for padding.1215 * @param array $args Uses 'selected', 'show_count', and 'value_field' keys, if they exist.1216 * See {@see wp_dropdown_categories()}.1217 */1218 public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {1219 $pad = str_repeat(' ', $depth * 3);1220 1221 /** This filter is documented in wp-includes/category-template.php */1222 $cat_name = apply_filters( 'list_cats', $category->name, $category );1223 1224 if ( isset( $args['value_field'] ) && isset( $category->{$args['value_field']} ) ) {1225 $value_field = $args['value_field'];1226 } else {1227 $value_field = 'term_id';1228 }1229 1230 $output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr( $category->{$value_field} ) . "\"";1231 1232 // Type-juggling causes false matches, so we force everything to a string.1233 if ( (string) $category->{$value_field} === (string) $args['selected'] )1234 $output .= ' selected="selected"';1235 $output .= '>';1236 $output .= $pad.$cat_name;1237 if ( $args['show_count'] )1238 $output .= ' ('. number_format_i18n( $category->count ) .')';1239 $output .= "</option>\n";1240 }1241 }1242 1243 //1244 // Tags1245 //1246 1247 /**1248 * Retrieve the link to the tag.1249 *1250 * @since 2.3.01251 * @see get_term_link()1252 *1253 * @param int|object $tag Tag ID or object.1254 * @return string Link on success, empty string if tag does not exist.1255 */1256 function get_tag_link( $tag ) {1257 if ( ! is_object( $tag ) )1258 $tag = (int) $tag;1259 1260 $tag = get_term_link( $tag, 'post_tag' );1261 1262 if ( is_wp_error( $tag ) )1263 return '';1264 1265 return $tag;1266 }1267 1268 /**1269 * Retrieve the tags for a post.1270 *1271 * @since 2.3.01272 *1273 * @param int $id Post ID.1274 * @return array|false|WP_Error Array of tag objects on success, false on failure.1275 */1276 function get_the_tags( $id = 0 ) {1277 1278 /**1279 * Filter the array of tags for the given post.1280 *1281 * @since 2.3.01282 *1283 * @see get_the_terms()1284 *1285 * @param array $terms An array of tags for the given post.1286 */1287 return apply_filters( 'get_the_tags', get_the_terms( $id, 'post_tag' ) );1288 }1289 1290 /**1291 * Retrieve the tags for a post formatted as a string.1292 *1293 * @since 2.3.01294 *1295 * @param string $before Optional. Before tags.1296 * @param string $sep Optional. Between tags.1297 * @param string $after Optional. After tags.1298 * @param int $id Optional. Post ID. Defaults to the current post.1299 * @return string|false|WP_Error A list of tags on success, false if there are no terms, WP_Error on failure.1300 */1301 function get_the_tag_list( $before = '', $sep = '', $after = '', $id = 0 ) {1302 1303 /**1304 * Filter the tags list for a given post.1305 *1306 * @since 2.3.01307 *1308 * @param string $tag_list List of tags.1309 * @param string $before String to use before tags.1310 * @param string $sep String to use between the tags.1311 * @param string $after String to use after tags.1312 * @param int $id Post ID.1313 */1314 return apply_filters( 'the_tags', get_the_term_list( $id, 'post_tag', $before, $sep, $after ), $before, $sep, $after, $id );1315 }1316 1317 /**1318 * Retrieve the tags for a post.1319 *1320 * @since 2.3.01321 *1322 * @param string $before Optional. Before list.1323 * @param string $sep Optional. Separate items using this.1324 * @param string $after Optional. After list.1325 */1326 function the_tags( $before = null, $sep = ', ', $after = '' ) {1327 if ( null === $before )1328 $before = __('Tags: ');1329 echo get_the_tag_list($before, $sep, $after);1330 }1331 1332 /**1333 * Retrieve tag description.1334 *1335 * @since 2.8.01336 *1337 * @param int $tag Optional. Tag ID. Will use global tag ID by default.1338 * @return string Tag description, available.1339 */1340 function tag_description( $tag = 0 ) {1341 return term_description( $tag );1342 }1343 1344 /**1345 * Retrieve term description.1346 *1347 * @since 2.8.01348 *1349 * @param int $term Optional. Term ID. Will use global term ID by default.1350 * @param string $taxonomy Optional taxonomy name. Defaults to 'post_tag'.1351 * @return string Term description, available.1352 */1353 function term_description( $term = 0, $taxonomy = 'post_tag' ) {1354 if ( ! $term && ( is_tax() || is_tag() || is_category() ) ) {1355 $term = get_queried_object();1356 if ( $term ) {1357 $taxonomy = $term->taxonomy;1358 $term = $term->term_id;1359 }1360 }1361 $description = get_term_field( 'description', $term, $taxonomy );1362 return is_wp_error( $description ) ? '' : $description;1363 }1364 1365 /**1366 * Retrieve the terms of the taxonomy that are attached to the post.1367 *1368 * @since 2.5.01369 *1370 * @param int|object $post Post ID or object.1371 * @param string $taxonomy Taxonomy name.1372 * @return array|false|WP_Error Array of term objects on success, false if there are no terms1373 * or the post does not exist, WP_Error on failure.1374 */1375 function get_the_terms( $post, $taxonomy ) {1376 if ( ! $post = get_post( $post ) )1377 return false;1378 1379 $terms = get_object_term_cache( $post->ID, $taxonomy );1380 if ( false === $terms ) {1381 $terms = wp_get_object_terms( $post->ID, $taxonomy );1382 wp_cache_add($post->ID, $terms, $taxonomy . '_relationships');1383 }1384 1385 /**1386 * Filter the list of terms attached to the given post.1387 *1388 * @since 3.1.01389 *1390 * @param array|WP_Error $terms List of attached terms, or WP_Error on failure.1391 * @param int $post_id Post ID.1392 * @param string $taxonomy Name of the taxonomy.1393 */1394 $terms = apply_filters( 'get_the_terms', $terms, $post->ID, $taxonomy );1395 1396 if ( empty( $terms ) )1397 return false;1398 1399 return $terms;1400 }1401 1402 /**1403 * Retrieve a post's terms as a list with specified format.1404 *1405 * @since 2.5.01406 *1407 * @param int $id Post ID.1408 * @param string $taxonomy Taxonomy name.1409 * @param string $before Optional. Before list.1410 * @param string $sep Optional. Separate items using this.1411 * @param string $after Optional. After list.1412 * @return string|false|WP_Error A list of terms on success, false if there are no terms, WP_Error on failure.1413 */1414 function get_the_term_list( $id, $taxonomy, $before = '', $sep = '', $after = '' ) {1415 $terms = get_the_terms( $id, $taxonomy );1416 1417 if ( is_wp_error( $terms ) )1418 return $terms;1419 1420 if ( empty( $terms ) )1421 return false;1422 1423 $links = array();1424 1425 foreach ( $terms as $term ) {1426 $link = get_term_link( $term, $taxonomy );1427 if ( is_wp_error( $link ) ) {1428 return $link;1429 }1430 $links[] = '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a>';1431 }1432 1433 /**1434 * Filter the term links for a given taxonomy.1435 *1436 * The dynamic portion of the filter name, `$taxonomy`, refers1437 * to the taxonomy slug.1438 *1439 * @since 2.5.01440 *1441 * @param array $links An array of term links.1442 */1443 $term_links = apply_filters( "term_links-$taxonomy", $links );1444 1445 return $before . join( $sep, $term_links ) . $after;1446 }1447 1448 /**1449 * Display the terms in a list.1450 *1451 * @since 2.5.01452 *1453 * @param int $id Post ID.1454 * @param string $taxonomy Taxonomy name.1455 * @param string $before Optional. Before list.1456 * @param string $sep Optional. Separate items using this.1457 * @param string $after Optional. After list.1458 * @return false|void False on WordPress error.1459 */1460 function the_terms( $id, $taxonomy, $before = '', $sep = ', ', $after = '' ) {1461 $term_list = get_the_term_list( $id, $taxonomy, $before, $sep, $after );1462 1463 if ( is_wp_error( $term_list ) )1464 return false;1465 1466 /**1467 * Filter the list of terms to display.1468 *1469 * @since 2.9.01470 *1471 * @param array $term_list List of terms to display.1472 * @param string $taxonomy The taxonomy name.1473 * @param string $before String to use before the terms.1474 * @param string $sep String to use between the terms.1475 * @param string $after String to use after the terms.1476 */1477 echo apply_filters( 'the_terms', $term_list, $taxonomy, $before, $sep, $after );1478 }1479 1480 /**1481 * Check if the current post has any of given category.1482 *1483 * @since 3.1.01484 *1485 * @param string|int|array $category Optional. The category name/term_id/slug or array of them to check for.1486 * @param int|object $post Optional. Post to check instead of the current post.1487 * @return bool True if the current post has any of the given categories (or any category, if no category specified).1488 */1489 function has_category( $category = '', $post = null ) {1490 return has_term( $category, 'category', $post );1491 }1492 1493 /**1494 * Check if the current post has any of given tags.1495 *1496 * The given tags are checked against the post's tags' term_ids, names and slugs.1497 * Tags given as integers will only be checked against the post's tags' term_ids.1498 * If no tags are given, determines if post has any tags.1499 *1500 * Prior to v2.7 of WordPress, tags given as integers would also be checked against the post's tags' names and slugs (in addition to term_ids)1501 * Prior to v2.7, this function could only be used in the WordPress Loop.1502 * As of 2.7, the function can be used anywhere if it is provided a post ID or post object.1503 *1504 * @since 2.6.01505 *1506 * @param string|int|array $tag Optional. The tag name/term_id/slug or array of them to check for.1507 * @param int|object $post Optional. Post to check instead of the current post. (since 2.7.0)1508 * @return bool True if the current post has any of the given tags (or any tag, if no tag specified).1509 */1510 function has_tag( $tag = '', $post = null ) {1511 return has_term( $tag, 'post_tag', $post );1512 }1513 1514 /**1515 * Check if the current post has any of given terms.1516 *1517 * The given terms are checked against the post's terms' term_ids, names and slugs.1518 * Terms given as integers will only be checked against the post's terms' term_ids.1519 * If no terms are given, determines if post has any terms.1520 *1521 * @since 3.1.01522 *1523 * @param string|int|array $term Optional. The term name/term_id/slug or array of them to check for.1524 * @param string $taxonomy Taxonomy name1525 * @param int|object $post Optional. Post to check instead of the current post.1526 * @return bool True if the current post has any of the given tags (or any tag, if no tag specified).1527 */1528 function has_term( $term = '', $taxonomy = '', $post = null ) {1529 $post = get_post($post);1530 1531 if ( !$post )1532 return false;1533 1534 $r = is_object_in_term( $post->ID, $taxonomy, $term );1535 if ( is_wp_error( $r ) )1536 return false;1537 1538 return $r;1539 }
Note: See TracChangeset
for help on using the changeset viewer.