wp/wp-includes/category-template.php
changeset 0 d970ebf37754
child 5 5e2f62d02dcd
equal deleted inserted replaced
-1:000000000000 0:d970ebf37754
       
     1 <?php
       
     2 /**
       
     3  * Category Template Tags and API.
       
     4  *
       
     5  * @package WordPress
       
     6  * @subpackage Template
       
     7  */
       
     8 
       
     9 /**
       
    10  * Retrieve category link URL.
       
    11  *
       
    12  * @since 1.0.0
       
    13  * @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.0
       
    34  *
       
    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 	else
       
    51 		$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 ) ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $parent->name ) ) . '">'.$name.'</a>' . $separator;
       
    60 	else
       
    61 		$chain .= $name.$separator;
       
    62 	return $chain;
       
    63 }
       
    64 
       
    65 /**
       
    66  * Retrieve post categories.
       
    67  *
       
    68  * @since 0.71
       
    69  * @uses $post
       
    70  *
       
    71  * @param int $id Optional, default to current post ID. The post ID.
       
    72  * @return array
       
    73  */
       
    74 function get_the_category( $id = false ) {
       
    75 	$categories = get_the_terms( $id, 'category' );
       
    76 	if ( ! $categories || is_wp_error( $categories ) )
       
    77 		$categories = array();
       
    78 
       
    79 	$categories = array_values( $categories );
       
    80 
       
    81 	foreach ( array_keys( $categories ) as $key ) {
       
    82 		_make_cat_compat( $categories[$key] );
       
    83 	}
       
    84 
       
    85 	// Filter name is plural because we return alot of categories (possibly more than #13237) not just one
       
    86 	return apply_filters( 'get_the_categories', $categories );
       
    87 }
       
    88 
       
    89 /**
       
    90  * Sort categories by name.
       
    91  *
       
    92  * Used by usort() as a callback, should not be used directly. Can actually be
       
    93  * used to sort any term object.
       
    94  *
       
    95  * @since 2.3.0
       
    96  * @access private
       
    97  *
       
    98  * @param object $a
       
    99  * @param object $b
       
   100  * @return int
       
   101  */
       
   102 function _usort_terms_by_name( $a, $b ) {
       
   103 	return strcmp( $a->name, $b->name );
       
   104 }
       
   105 
       
   106 /**
       
   107  * Sort categories by ID.
       
   108  *
       
   109  * Used by usort() as a callback, should not be used directly. Can actually be
       
   110  * used to sort any term object.
       
   111  *
       
   112  * @since 2.3.0
       
   113  * @access private
       
   114  *
       
   115  * @param object $a
       
   116  * @param object $b
       
   117  * @return int
       
   118  */
       
   119 function _usort_terms_by_ID( $a, $b ) {
       
   120 	if ( $a->term_id > $b->term_id )
       
   121 		return 1;
       
   122 	elseif ( $a->term_id < $b->term_id )
       
   123 		return -1;
       
   124 	else
       
   125 		return 0;
       
   126 }
       
   127 
       
   128 /**
       
   129  * Retrieve category name based on category ID.
       
   130  *
       
   131  * @since 0.71
       
   132  *
       
   133  * @param int $cat_ID Category ID.
       
   134  * @return string|WP_Error Category name on success, WP_Error on failure.
       
   135  */
       
   136 function get_the_category_by_ID( $cat_ID ) {
       
   137 	$cat_ID = (int) $cat_ID;
       
   138 	$category = get_term( $cat_ID, 'category' );
       
   139 	if ( is_wp_error( $category ) )
       
   140 		return $category;
       
   141 	return $category->name;
       
   142 }
       
   143 
       
   144 /**
       
   145  * Retrieve category list in either HTML list or custom format.
       
   146  *
       
   147  * @since 1.5.1
       
   148  *
       
   149  * @param string $separator Optional, default is empty string. Separator for between the categories.
       
   150  * @param string $parents Optional. How to display the parents.
       
   151  * @param int $post_id Optional. Post ID to retrieve categories.
       
   152  * @return string
       
   153  */
       
   154 function get_the_category_list( $separator = '', $parents='', $post_id = false ) {
       
   155 	global $wp_rewrite;
       
   156 	if ( ! is_object_in_taxonomy( get_post_type( $post_id ), 'category' ) )
       
   157 		return apply_filters( 'the_category', '', $separator, $parents );
       
   158 
       
   159 	$categories = get_the_category( $post_id );
       
   160 	if ( empty( $categories ) )
       
   161 		return apply_filters( 'the_category', __( 'Uncategorized' ), $separator, $parents );
       
   162 
       
   163 	$rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';
       
   164 
       
   165 	$thelist = '';
       
   166 	if ( '' == $separator ) {
       
   167 		$thelist .= '<ul class="post-categories">';
       
   168 		foreach ( $categories as $category ) {
       
   169 			$thelist .= "\n\t<li>";
       
   170 			switch ( strtolower( $parents ) ) {
       
   171 				case 'multiple':
       
   172 					if ( $category->parent )
       
   173 						$thelist .= get_category_parents( $category->parent, true, $separator );
       
   174 					$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';
       
   175 					break;
       
   176 				case 'single':
       
   177 					$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>';
       
   178 					if ( $category->parent )
       
   179 						$thelist .= get_category_parents( $category->parent, false, $separator );
       
   180 					$thelist .= $category->name.'</a></li>';
       
   181 					break;
       
   182 				case '':
       
   183 				default:
       
   184 					$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';
       
   185 			}
       
   186 		}
       
   187 		$thelist .= '</ul>';
       
   188 	} else {
       
   189 		$i = 0;
       
   190 		foreach ( $categories as $category ) {
       
   191 			if ( 0 < $i )
       
   192 				$thelist .= $separator;
       
   193 			switch ( strtolower( $parents ) ) {
       
   194 				case 'multiple':
       
   195 					if ( $category->parent )
       
   196 						$thelist .= get_category_parents( $category->parent, true, $separator );
       
   197 					$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>' . $category->name.'</a>';
       
   198 					break;
       
   199 				case 'single':
       
   200 					$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>';
       
   201 					if ( $category->parent )
       
   202 						$thelist .= get_category_parents( $category->parent, false, $separator );
       
   203 					$thelist .= "$category->name</a>";
       
   204 					break;
       
   205 				case '':
       
   206 				default:
       
   207 					$thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>' . $category->name.'</a>';
       
   208 			}
       
   209 			++$i;
       
   210 		}
       
   211 	}
       
   212 	return apply_filters( 'the_category', $thelist, $separator, $parents );
       
   213 }
       
   214 
       
   215 /**
       
   216  * Check if the current post in within any of the given categories.
       
   217  *
       
   218  * The given categories are checked against the post's categories' term_ids, names and slugs.
       
   219  * Categories given as integers will only be checked against the post's categories' term_ids.
       
   220  *
       
   221  * Prior to v2.5 of WordPress, category names were not supported.
       
   222  * Prior to v2.7, category slugs were not supported.
       
   223  * Prior to v2.7, only one category could be compared: in_category( $single_category ).
       
   224  * Prior to v2.7, this function could only be used in the WordPress Loop.
       
   225  * As of 2.7, the function can be used anywhere if it is provided a post ID or post object.
       
   226  *
       
   227  * @since 1.2.0
       
   228  * @uses has_category()
       
   229  *
       
   230  * @param int|string|array $category Category ID, name or slug, or array of said.
       
   231  * @param int|object $post Optional. Post to check instead of the current post. (since 2.7.0)
       
   232  * @return bool True if the current post is in any of the given categories.
       
   233  */
       
   234 function in_category( $category, $post = null ) {
       
   235 	if ( empty( $category ) )
       
   236 		return false;
       
   237 
       
   238 	return has_category( $category, $post );
       
   239 }
       
   240 
       
   241 /**
       
   242  * Display the category list for the post.
       
   243  *
       
   244  * @since 0.71
       
   245  *
       
   246  * @param string $separator Optional, default is empty string. Separator for between the categories.
       
   247  * @param string $parents Optional. How to display the parents.
       
   248  * @param int $post_id Optional. Post ID to retrieve categories.
       
   249  */
       
   250 function the_category( $separator = '', $parents='', $post_id = false ) {
       
   251 	echo get_the_category_list( $separator, $parents, $post_id );
       
   252 }
       
   253 
       
   254 /**
       
   255  * Retrieve category description.
       
   256  *
       
   257  * @since 1.0.0
       
   258  *
       
   259  * @param int $category Optional. Category ID. Will use global category ID by default.
       
   260  * @return string Category description, available.
       
   261  */
       
   262 function category_description( $category = 0 ) {
       
   263 	return term_description( $category, 'category' );
       
   264 }
       
   265 
       
   266 /**
       
   267  * Display or retrieve the HTML dropdown list of categories.
       
   268  *
       
   269  * The list of arguments is below:
       
   270  *     'show_option_all' (string) - Text to display for showing all categories.
       
   271  *     'show_option_none' (string) - Text to display for showing no categories.
       
   272  *     'orderby' (string) default is 'ID' - What column to use for ordering the
       
   273  * categories.
       
   274  *     'order' (string) default is 'ASC' - What direction to order categories.
       
   275  *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
       
   276  * in the category.
       
   277  *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
       
   278  * don't have any posts attached to them.
       
   279  *     'child_of' (int) default is 0 - See {@link get_categories()}.
       
   280  *     'exclude' (string) - See {@link get_categories()}.
       
   281  *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
       
   282  *     'depth' (int) - The max depth.
       
   283  *     'tab_index' (int) - Tab index for select element.
       
   284  *     'name' (string) - The name attribute value for select element.
       
   285  *     'id' (string) - The ID attribute value for select element. Defaults to name if omitted.
       
   286  *     'class' (string) - The class attribute value for select element.
       
   287  *     'selected' (int) - Which category ID is selected.
       
   288  *     'taxonomy' (string) - The name of the taxonomy to retrieve. Defaults to category.
       
   289  *
       
   290  * The 'hierarchical' argument, which is disabled by default, will override the
       
   291  * depth argument, unless it is true. When the argument is false, it will
       
   292  * display all of the categories. When it is enabled it will use the value in
       
   293  * the 'depth' argument.
       
   294  *
       
   295  * @since 2.1.0
       
   296  *
       
   297  * @param string|array $args Optional. Override default arguments.
       
   298  * @return string HTML content only if 'echo' argument is 0.
       
   299  */
       
   300 function wp_dropdown_categories( $args = '' ) {
       
   301 	$defaults = array(
       
   302 		'show_option_all' => '', 'show_option_none' => '',
       
   303 		'orderby' => 'id', 'order' => 'ASC',
       
   304 		'show_count' => 0,
       
   305 		'hide_empty' => 1, 'child_of' => 0,
       
   306 		'exclude' => '', 'echo' => 1,
       
   307 		'selected' => 0, 'hierarchical' => 0,
       
   308 		'name' => 'cat', 'id' => '',
       
   309 		'class' => 'postform', 'depth' => 0,
       
   310 		'tab_index' => 0, 'taxonomy' => 'category',
       
   311 		'hide_if_empty' => false
       
   312 	);
       
   313 
       
   314 	$defaults['selected'] = ( is_category() ) ? get_query_var( 'cat' ) : 0;
       
   315 
       
   316 	// Back compat.
       
   317 	if ( isset( $args['type'] ) && 'link' == $args['type'] ) {
       
   318 		_deprecated_argument( __FUNCTION__, '3.0', '' );
       
   319 		$args['taxonomy'] = 'link_category';
       
   320 	}
       
   321 
       
   322 	$r = wp_parse_args( $args, $defaults );
       
   323 
       
   324 	if ( !isset( $r['pad_counts'] ) && $r['show_count'] && $r['hierarchical'] ) {
       
   325 		$r['pad_counts'] = true;
       
   326 	}
       
   327 
       
   328 	extract( $r );
       
   329 
       
   330 	$tab_index_attribute = '';
       
   331 	if ( (int) $tab_index > 0 )
       
   332 		$tab_index_attribute = " tabindex=\"$tab_index\"";
       
   333 
       
   334 	$categories = get_terms( $taxonomy, $r );
       
   335 	$name = esc_attr( $name );
       
   336 	$class = esc_attr( $class );
       
   337 	$id = $id ? esc_attr( $id ) : $name;
       
   338 
       
   339 	if ( ! $r['hide_if_empty'] || ! empty($categories) )
       
   340 		$output = "<select name='$name' id='$id' class='$class' $tab_index_attribute>\n";
       
   341 	else
       
   342 		$output = '';
       
   343 
       
   344 	if ( empty($categories) && ! $r['hide_if_empty'] && !empty($show_option_none) ) {
       
   345 		$show_option_none = apply_filters( 'list_cats', $show_option_none );
       
   346 		$output .= "\t<option value='-1' selected='selected'>$show_option_none</option>\n";
       
   347 	}
       
   348 
       
   349 	if ( ! empty( $categories ) ) {
       
   350 
       
   351 		if ( $show_option_all ) {
       
   352 			$show_option_all = apply_filters( 'list_cats', $show_option_all );
       
   353 			$selected = ( '0' === strval($r['selected']) ) ? " selected='selected'" : '';
       
   354 			$output .= "\t<option value='0'$selected>$show_option_all</option>\n";
       
   355 		}
       
   356 
       
   357 		if ( $show_option_none ) {
       
   358 			$show_option_none = apply_filters( 'list_cats', $show_option_none );
       
   359 			$selected = ( '-1' === strval($r['selected']) ) ? " selected='selected'" : '';
       
   360 			$output .= "\t<option value='-1'$selected>$show_option_none</option>\n";
       
   361 		}
       
   362 
       
   363 		if ( $hierarchical )
       
   364 			$depth = $r['depth'];  // Walk the full depth.
       
   365 		else
       
   366 			$depth = -1; // Flat.
       
   367 
       
   368 		$output .= walk_category_dropdown_tree( $categories, $depth, $r );
       
   369 	}
       
   370 
       
   371 	if ( ! $r['hide_if_empty'] || ! empty($categories) )
       
   372 		$output .= "</select>\n";
       
   373 
       
   374 	$output = apply_filters( 'wp_dropdown_cats', $output );
       
   375 
       
   376 	if ( $echo )
       
   377 		echo $output;
       
   378 
       
   379 	return $output;
       
   380 }
       
   381 
       
   382 /**
       
   383  * Display or retrieve the HTML list of categories.
       
   384  *
       
   385  * The list of arguments is below:
       
   386  *     'show_option_all' (string) - Text to display for showing all categories.
       
   387  *     'orderby' (string) default is 'ID' - What column to use for ordering the
       
   388  * categories.
       
   389  *     'order' (string) default is 'ASC' - What direction to order categories.
       
   390  *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
       
   391  * in the category.
       
   392  *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
       
   393  * don't have any posts attached to them.
       
   394  *     'use_desc_for_title' (bool|int) default is 1 - Whether to use the
       
   395  * description instead of the category title.
       
   396  *     'feed' - See {@link get_categories()}.
       
   397  *     'feed_type' - See {@link get_categories()}.
       
   398  *     'feed_image' - See {@link get_categories()}.
       
   399  *     'child_of' (int) default is 0 - See {@link get_categories()}.
       
   400  *     'exclude' (string) - See {@link get_categories()}.
       
   401  *     'exclude_tree' (string) - See {@link get_categories()}.
       
   402  *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
       
   403  *     'current_category' (int) - See {@link get_categories()}.
       
   404  *     'hierarchical' (bool) - See {@link get_categories()}.
       
   405  *     'title_li' (string) - See {@link get_categories()}.
       
   406  *     'depth' (int) - The max depth.
       
   407  *
       
   408  * @since 2.1.0
       
   409  *
       
   410  * @param string|array $args Optional. Override default arguments.
       
   411  * @return string HTML content only if 'echo' argument is 0.
       
   412  */
       
   413 function wp_list_categories( $args = '' ) {
       
   414 	$defaults = array(
       
   415 		'show_option_all' => '', 'show_option_none' => __('No categories'),
       
   416 		'orderby' => 'name', 'order' => 'ASC',
       
   417 		'style' => 'list',
       
   418 		'show_count' => 0, 'hide_empty' => 1,
       
   419 		'use_desc_for_title' => 1, 'child_of' => 0,
       
   420 		'feed' => '', 'feed_type' => '',
       
   421 		'feed_image' => '', 'exclude' => '',
       
   422 		'exclude_tree' => '', 'current_category' => 0,
       
   423 		'hierarchical' => true, 'title_li' => __( 'Categories' ),
       
   424 		'echo' => 1, 'depth' => 0,
       
   425 		'taxonomy' => 'category'
       
   426 	);
       
   427 
       
   428 	$r = wp_parse_args( $args, $defaults );
       
   429 
       
   430 	if ( !isset( $r['pad_counts'] ) && $r['show_count'] && $r['hierarchical'] )
       
   431 		$r['pad_counts'] = true;
       
   432 
       
   433 	if ( true == $r['hierarchical'] ) {
       
   434 		$r['exclude_tree'] = $r['exclude'];
       
   435 		$r['exclude'] = '';
       
   436 	}
       
   437 
       
   438 	if ( !isset( $r['class'] ) )
       
   439 		$r['class'] = ( 'category' == $r['taxonomy'] ) ? 'categories' : $r['taxonomy'];
       
   440 
       
   441 	extract( $r );
       
   442 
       
   443 	if ( !taxonomy_exists($taxonomy) )
       
   444 		return false;
       
   445 
       
   446 	$categories = get_categories( $r );
       
   447 
       
   448 	$output = '';
       
   449 	if ( $title_li && 'list' == $style )
       
   450 			$output = '<li class="' . esc_attr( $class ) . '">' . $title_li . '<ul>';
       
   451 
       
   452 	if ( empty( $categories ) ) {
       
   453 		if ( ! empty( $show_option_none ) ) {
       
   454 			if ( 'list' == $style )
       
   455 				$output .= '<li>' . $show_option_none . '</li>';
       
   456 			else
       
   457 				$output .= $show_option_none;
       
   458 		}
       
   459 	} else {
       
   460 		if ( ! empty( $show_option_all ) ) {
       
   461 			$posts_page = ( 'page' == get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) ) ? get_permalink( get_option( 'page_for_posts' ) ) : home_url( '/' );
       
   462 			$posts_page = esc_url( $posts_page );
       
   463 			if ( 'list' == $style )
       
   464 				$output .= "<li><a href='$posts_page'>$show_option_all</a></li>";
       
   465 			else
       
   466 				$output .= "<a href='$posts_page'>$show_option_all</a>";
       
   467 		}
       
   468 
       
   469 		if ( empty( $r['current_category'] ) && ( is_category() || is_tax() || is_tag() ) ) {
       
   470 			$current_term_object = get_queried_object();
       
   471 			if ( $current_term_object && $r['taxonomy'] === $current_term_object->taxonomy )
       
   472 				$r['current_category'] = get_queried_object_id();
       
   473 		}
       
   474 
       
   475 		if ( $hierarchical )
       
   476 			$depth = $r['depth'];
       
   477 		else
       
   478 			$depth = -1; // Flat.
       
   479 
       
   480 		$output .= walk_category_tree( $categories, $depth, $r );
       
   481 	}
       
   482 
       
   483 	if ( $title_li && 'list' == $style )
       
   484 		$output .= '</ul></li>';
       
   485 
       
   486 	$output = apply_filters( 'wp_list_categories', $output, $args );
       
   487 
       
   488 	if ( $echo )
       
   489 		echo $output;
       
   490 	else
       
   491 		return $output;
       
   492 }
       
   493 
       
   494 /**
       
   495  * Display tag cloud.
       
   496  *
       
   497  * The text size is set by the 'smallest' and 'largest' arguments, which will
       
   498  * use the 'unit' argument value for the CSS text size unit. The 'format'
       
   499  * argument can be 'flat' (default), 'list', or 'array'. The flat value for the
       
   500  * 'format' argument will separate tags with spaces. The list value for the
       
   501  * 'format' argument will format the tags in a UL HTML list. The array value for
       
   502  * the 'format' argument will return in PHP array type format.
       
   503  *
       
   504  * The 'orderby' argument will accept 'name' or 'count' and defaults to 'name'.
       
   505  * The 'order' is the direction to sort, defaults to 'ASC' and can be 'DESC'.
       
   506  *
       
   507  * The 'number' argument is how many tags to return. By default, the limit will
       
   508  * be to return the top 45 tags in the tag cloud list.
       
   509  *
       
   510  * The 'topic_count_text_callback' argument is a function, which, given the count
       
   511  * of the posts  with that tag, returns a text for the tooltip of the tag link.
       
   512  *
       
   513  * The 'exclude' and 'include' arguments are used for the {@link get_tags()}
       
   514  * function. Only one should be used, because only one will be used and the
       
   515  * other ignored, if they are both set.
       
   516  *
       
   517  * @since 2.3.0
       
   518  *
       
   519  * @param array|string $args Optional. Override default arguments.
       
   520  * @return array Generated tag cloud, only if no failures and 'array' is set for the 'format' argument.
       
   521  */
       
   522 function wp_tag_cloud( $args = '' ) {
       
   523 	$defaults = array(
       
   524 		'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45,
       
   525 		'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC',
       
   526 		'exclude' => '', 'include' => '', 'link' => 'view', 'taxonomy' => 'post_tag', 'echo' => true
       
   527 	);
       
   528 	$args = wp_parse_args( $args, $defaults );
       
   529 
       
   530 	$tags = get_terms( $args['taxonomy'], array_merge( $args, array( 'orderby' => 'count', 'order' => 'DESC' ) ) ); // Always query top tags
       
   531 
       
   532 	if ( empty( $tags ) || is_wp_error( $tags ) )
       
   533 		return;
       
   534 
       
   535 	foreach ( $tags as $key => $tag ) {
       
   536 		if ( 'edit' == $args['link'] )
       
   537 			$link = get_edit_tag_link( $tag->term_id, $tag->taxonomy );
       
   538 		else
       
   539 			$link = get_term_link( intval($tag->term_id), $tag->taxonomy );
       
   540 		if ( is_wp_error( $link ) )
       
   541 			return false;
       
   542 
       
   543 		$tags[ $key ]->link = $link;
       
   544 		$tags[ $key ]->id = $tag->term_id;
       
   545 	}
       
   546 
       
   547 	$return = wp_generate_tag_cloud( $tags, $args ); // Here's where those top tags get sorted according to $args
       
   548 
       
   549 	$return = apply_filters( 'wp_tag_cloud', $return, $args );
       
   550 
       
   551 	if ( 'array' == $args['format'] || empty($args['echo']) )
       
   552 		return $return;
       
   553 
       
   554 	echo $return;
       
   555 }
       
   556 
       
   557 /**
       
   558  * Default text for tooltip for tag links
       
   559  *
       
   560  * @param integer $count number of posts with that tag
       
   561  * @return string text for the tooltip of a tag link.
       
   562  */
       
   563 function default_topic_count_text( $count ) {
       
   564 	return sprintf( _n('%s topic', '%s topics', $count), number_format_i18n( $count ) );
       
   565 }
       
   566 
       
   567 /**
       
   568  * Default topic count scaling for tag links
       
   569  *
       
   570  * @param integer $count number of posts with that tag
       
   571  * @return integer scaled count
       
   572  */
       
   573 function default_topic_count_scale( $count ) {
       
   574 	return round(log10($count + 1) * 100);
       
   575 }
       
   576 
       
   577 /**
       
   578  * Generates a tag cloud (heatmap) from provided data.
       
   579  *
       
   580  * The text size is set by the 'smallest' and 'largest' arguments, which will
       
   581  * use the 'unit' argument value for the CSS text size unit. The 'format'
       
   582  * argument can be 'flat' (default), 'list', or 'array'. The flat value for the
       
   583  * 'format' argument will separate tags with spaces. The list value for the
       
   584  * 'format' argument will format the tags in a UL HTML list. The array value for
       
   585  * the 'format' argument will return in PHP array type format.
       
   586  *
       
   587  * The 'tag_cloud_sort' filter allows you to override the sorting.
       
   588  * Passed to the filter: $tags array and $args array, has to return the $tags array
       
   589  * after sorting it.
       
   590  *
       
   591  * The 'orderby' argument will accept 'name' or 'count' and defaults to 'name'.
       
   592  * The 'order' is the direction to sort, defaults to 'ASC' and can be 'DESC' or
       
   593  * 'RAND'.
       
   594  *
       
   595  * The 'number' argument is how many tags to return. By default, the limit will
       
   596  * be to return the entire tag cloud list.
       
   597  *
       
   598  * The 'topic_count_text_callback' argument is a function, which given the count
       
   599  * of the posts  with that tag returns a text for the tooltip of the tag link.
       
   600  *
       
   601  * @todo Complete functionality.
       
   602  * @since 2.3.0
       
   603  *
       
   604  * @param array $tags List of tags.
       
   605  * @param string|array $args Optional, override default arguments.
       
   606  * @return string
       
   607  */
       
   608 function wp_generate_tag_cloud( $tags, $args = '' ) {
       
   609 	$defaults = array(
       
   610 		'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 0,
       
   611 		'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC',
       
   612 		'topic_count_text_callback' => 'default_topic_count_text',
       
   613 		'topic_count_scale_callback' => 'default_topic_count_scale', 'filter' => 1,
       
   614 	);
       
   615 
       
   616 	if ( !isset( $args['topic_count_text_callback'] ) && isset( $args['single_text'] ) && isset( $args['multiple_text'] ) ) {
       
   617 		$body = 'return sprintf (
       
   618 			_n(' . var_export($args['single_text'], true) . ', ' . var_export($args['multiple_text'], true) . ', $count),
       
   619 			number_format_i18n( $count ));';
       
   620 		$args['topic_count_text_callback'] = create_function('$count', $body);
       
   621 	}
       
   622 
       
   623 	$args = wp_parse_args( $args, $defaults );
       
   624 	extract( $args );
       
   625 
       
   626 	if ( empty( $tags ) )
       
   627 		return;
       
   628 
       
   629 	$tags_sorted = apply_filters( 'tag_cloud_sort', $tags, $args );
       
   630 	if ( $tags_sorted != $tags  ) { // the tags have been sorted by a plugin
       
   631 		$tags = $tags_sorted;
       
   632 		unset($tags_sorted);
       
   633 	} else {
       
   634 		if ( 'RAND' == $order ) {
       
   635 			shuffle($tags);
       
   636 		} else {
       
   637 			// SQL cannot save you; this is a second (potentially different) sort on a subset of data.
       
   638 			if ( 'name' == $orderby )
       
   639 				uasort( $tags, '_wp_object_name_sort_cb' );
       
   640 			else
       
   641 				uasort( $tags, '_wp_object_count_sort_cb' );
       
   642 
       
   643 			if ( 'DESC' == $order )
       
   644 				$tags = array_reverse( $tags, true );
       
   645 		}
       
   646 	}
       
   647 
       
   648 	if ( $number > 0 )
       
   649 		$tags = array_slice($tags, 0, $number);
       
   650 
       
   651 	$counts = array();
       
   652 	$real_counts = array(); // For the alt tag
       
   653 	foreach ( (array) $tags as $key => $tag ) {
       
   654 		$real_counts[ $key ] = $tag->count;
       
   655 		$counts[ $key ] = $topic_count_scale_callback($tag->count);
       
   656 	}
       
   657 
       
   658 	$min_count = min( $counts );
       
   659 	$spread = max( $counts ) - $min_count;
       
   660 	if ( $spread <= 0 )
       
   661 		$spread = 1;
       
   662 	$font_spread = $largest - $smallest;
       
   663 	if ( $font_spread < 0 )
       
   664 		$font_spread = 1;
       
   665 	$font_step = $font_spread / $spread;
       
   666 
       
   667 	$a = array();
       
   668 
       
   669 	foreach ( $tags as $key => $tag ) {
       
   670 		$count = $counts[ $key ];
       
   671 		$real_count = $real_counts[ $key ];
       
   672 		$tag_link = '#' != $tag->link ? esc_url( $tag->link ) : '#';
       
   673 		$tag_id = isset($tags[ $key ]->id) ? $tags[ $key ]->id : $key;
       
   674 		$tag_name = $tags[ $key ]->name;
       
   675 		$a[] = "<a href='$tag_link' class='tag-link-$tag_id' title='" . esc_attr( call_user_func( $topic_count_text_callback, $real_count, $tag, $args ) ) . "' style='font-size: " .
       
   676 			str_replace( ',', '.', ( $smallest + ( ( $count - $min_count ) * $font_step ) ) )
       
   677 			. "$unit;'>$tag_name</a>";
       
   678 	}
       
   679 
       
   680 	switch ( $format ) :
       
   681 	case 'array' :
       
   682 		$return =& $a;
       
   683 		break;
       
   684 	case 'list' :
       
   685 		$return = "<ul class='wp-tag-cloud'>\n\t<li>";
       
   686 		$return .= join( "</li>\n\t<li>", $a );
       
   687 		$return .= "</li>\n</ul>\n";
       
   688 		break;
       
   689 	default :
       
   690 		$return = join( $separator, $a );
       
   691 		break;
       
   692 	endswitch;
       
   693 
       
   694 	if ( $filter )
       
   695 		return apply_filters( 'wp_generate_tag_cloud', $return, $tags, $args );
       
   696 	else
       
   697 		return $return;
       
   698 }
       
   699 
       
   700 /**
       
   701  * Callback for comparing objects based on name
       
   702  *
       
   703  * @since 3.1.0
       
   704  * @access private
       
   705  */
       
   706 function _wp_object_name_sort_cb( $a, $b ) {
       
   707 	return strnatcasecmp( $a->name, $b->name );
       
   708 }
       
   709 
       
   710 /**
       
   711  * Callback for comparing objects based on count
       
   712  *
       
   713  * @since 3.1.0
       
   714  * @access private
       
   715  */
       
   716 function _wp_object_count_sort_cb( $a, $b ) {
       
   717 	return ( $a->count > $b->count );
       
   718 }
       
   719 
       
   720 //
       
   721 // Helper functions
       
   722 //
       
   723 
       
   724 /**
       
   725  * Retrieve HTML list content for category list.
       
   726  *
       
   727  * @uses Walker_Category to create HTML list content.
       
   728  * @since 2.1.0
       
   729  * @see Walker_Category::walk() for parameters and return description.
       
   730  */
       
   731 function walk_category_tree() {
       
   732 	$args = func_get_args();
       
   733 	// the user's options are the third parameter
       
   734 	if ( empty($args[2]['walker']) || !is_a($args[2]['walker'], 'Walker') )
       
   735 		$walker = new Walker_Category;
       
   736 	else
       
   737 		$walker = $args[2]['walker'];
       
   738 
       
   739 	return call_user_func_array(array( &$walker, 'walk' ), $args );
       
   740 }
       
   741 
       
   742 /**
       
   743  * Retrieve HTML dropdown (select) content for category list.
       
   744  *
       
   745  * @uses Walker_CategoryDropdown to create HTML dropdown content.
       
   746  * @since 2.1.0
       
   747  * @see Walker_CategoryDropdown::walk() for parameters and return description.
       
   748  */
       
   749 function walk_category_dropdown_tree() {
       
   750 	$args = func_get_args();
       
   751 	// the user's options are the third parameter
       
   752 	if ( empty($args[2]['walker']) || !is_a($args[2]['walker'], 'Walker') )
       
   753 		$walker = new Walker_CategoryDropdown;
       
   754 	else
       
   755 		$walker = $args[2]['walker'];
       
   756 
       
   757 	return call_user_func_array(array( &$walker, 'walk' ), $args );
       
   758 }
       
   759 
       
   760 /**
       
   761  * Create HTML list of categories.
       
   762  *
       
   763  * @package WordPress
       
   764  * @since 2.1.0
       
   765  * @uses Walker
       
   766  */
       
   767 class Walker_Category extends Walker {
       
   768 	/**
       
   769 	 * What the class handles.
       
   770 	 *
       
   771 	 * @see Walker::$tree_type
       
   772 	 * @since 2.1.0
       
   773 	 * @var string
       
   774 	 */
       
   775 	var $tree_type = 'category';
       
   776 
       
   777 	/**
       
   778 	 * Database fields to use.
       
   779 	 *
       
   780 	 * @see Walker::$db_fields
       
   781 	 * @since 2.1.0
       
   782 	 * @todo Decouple this
       
   783 	 * @var array
       
   784 	 */
       
   785 	var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
       
   786 
       
   787 	/**
       
   788 	 * Starts the list before the elements are added.
       
   789 	 *
       
   790 	 * @see Walker::start_lvl()
       
   791 	 *
       
   792 	 * @since 2.1.0
       
   793 	 *
       
   794 	 * @param string $output Passed by reference. Used to append additional content.
       
   795 	 * @param int    $depth  Depth of category. Used for tab indentation.
       
   796 	 * @param array  $args   An array of arguments. Will only append content if style argument value is 'list'.
       
   797 	 *                       @see wp_list_categories()
       
   798 	 */
       
   799 	function start_lvl( &$output, $depth = 0, $args = array() ) {
       
   800 		if ( 'list' != $args['style'] )
       
   801 			return;
       
   802 
       
   803 		$indent = str_repeat("\t", $depth);
       
   804 		$output .= "$indent<ul class='children'>\n";
       
   805 	}
       
   806 
       
   807 	/**
       
   808 	 * Ends the list of after the elements are added.
       
   809 	 *
       
   810 	 * @see Walker::end_lvl()
       
   811 	 *
       
   812 	 * @since 2.1.0
       
   813 	 *
       
   814 	 * @param string $output Passed by reference. Used to append additional content.
       
   815 	 * @param int    $depth  Depth of category. Used for tab indentation.
       
   816 	 * @param array  $args   An array of arguments. Will only append content if style argument value is 'list'.
       
   817 	 *                       @wsee wp_list_categories()
       
   818 	 */
       
   819 	function end_lvl( &$output, $depth = 0, $args = array() ) {
       
   820 		if ( 'list' != $args['style'] )
       
   821 			return;
       
   822 
       
   823 		$indent = str_repeat("\t", $depth);
       
   824 		$output .= "$indent</ul>\n";
       
   825 	}
       
   826 
       
   827 	/**
       
   828 	 * Start the element output.
       
   829 	 *
       
   830 	 * @see Walker::start_el()
       
   831 	 *
       
   832 	 * @since 2.1.0
       
   833 	 *
       
   834 	 * @param string $output   Passed by reference. Used to append additional content.
       
   835 	 * @param object $category Category data object.
       
   836 	 * @param int    $depth    Depth of category in reference to parents. Default 0.
       
   837 	 * @param array  $args     An array of arguments. @see wp_list_categories()
       
   838 	 * @param int    $id       ID of the current category.
       
   839 	 */
       
   840 	function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
       
   841 		extract($args);
       
   842 
       
   843 		$cat_name = esc_attr( $category->name );
       
   844 		$cat_name = apply_filters( 'list_cats', $cat_name, $category );
       
   845 		$link = '<a href="' . esc_url( get_term_link($category) ) . '" ';
       
   846 		if ( $use_desc_for_title == 0 || empty($category->description) )
       
   847 			$link .= 'title="' . esc_attr( sprintf(__( 'View all posts filed under %s' ), $cat_name) ) . '"';
       
   848 		else
       
   849 			$link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
       
   850 		$link .= '>';
       
   851 		$link .= $cat_name . '</a>';
       
   852 
       
   853 		if ( !empty($feed_image) || !empty($feed) ) {
       
   854 			$link .= ' ';
       
   855 
       
   856 			if ( empty($feed_image) )
       
   857 				$link .= '(';
       
   858 
       
   859 			$link .= '<a href="' . esc_url( get_term_feed_link( $category->term_id, $category->taxonomy, $feed_type ) ) . '"';
       
   860 
       
   861 			if ( empty($feed) ) {
       
   862 				$alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';
       
   863 			} else {
       
   864 				$title = ' title="' . $feed . '"';
       
   865 				$alt = ' alt="' . $feed . '"';
       
   866 				$name = $feed;
       
   867 				$link .= $title;
       
   868 			}
       
   869 
       
   870 			$link .= '>';
       
   871 
       
   872 			if ( empty($feed_image) )
       
   873 				$link .= $name;
       
   874 			else
       
   875 				$link .= "<img src='$feed_image'$alt$title" . ' />';
       
   876 
       
   877 			$link .= '</a>';
       
   878 
       
   879 			if ( empty($feed_image) )
       
   880 				$link .= ')';
       
   881 		}
       
   882 
       
   883 		if ( !empty($show_count) )
       
   884 			$link .= ' (' . intval($category->count) . ')';
       
   885 
       
   886 		if ( 'list' == $args['style'] ) {
       
   887 			$output .= "\t<li";
       
   888 			$class = 'cat-item cat-item-' . $category->term_id;
       
   889 			if ( !empty($current_category) ) {
       
   890 				$_current_category = get_term( $current_category, $category->taxonomy );
       
   891 				if ( $category->term_id == $current_category )
       
   892 					$class .=  ' current-cat';
       
   893 				elseif ( $category->term_id == $_current_category->parent )
       
   894 					$class .=  ' current-cat-parent';
       
   895 			}
       
   896 			$output .=  ' class="' . $class . '"';
       
   897 			$output .= ">$link\n";
       
   898 		} else {
       
   899 			$output .= "\t$link<br />\n";
       
   900 		}
       
   901 	}
       
   902 
       
   903 	/**
       
   904 	 * Ends the element output, if needed.
       
   905 	 *
       
   906 	 * @see Walker::end_el()
       
   907 	 *
       
   908 	 * @since 2.1.0
       
   909 	 *
       
   910 	 * @param string $output Passed by reference. Used to append additional content.
       
   911 	 * @param object $page   Not used.
       
   912 	 * @param int    $depth  Depth of category. Not used.
       
   913 	 * @param array  $args   An array of arguments. Only uses 'list' for whether should append to output. @see wp_list_categories()
       
   914 	 */
       
   915 	function end_el( &$output, $page, $depth = 0, $args = array() ) {
       
   916 		if ( 'list' != $args['style'] )
       
   917 			return;
       
   918 
       
   919 		$output .= "</li>\n";
       
   920 	}
       
   921 
       
   922 }
       
   923 
       
   924 /**
       
   925  * Create HTML dropdown list of Categories.
       
   926  *
       
   927  * @package WordPress
       
   928  * @since 2.1.0
       
   929  * @uses Walker
       
   930  */
       
   931 class Walker_CategoryDropdown extends Walker {
       
   932 	/**
       
   933 	 * @see Walker::$tree_type
       
   934 	 * @since 2.1.0
       
   935 	 * @var string
       
   936 	 */
       
   937 	var $tree_type = 'category';
       
   938 
       
   939 	/**
       
   940 	 * @see Walker::$db_fields
       
   941 	 * @since 2.1.0
       
   942 	 * @todo Decouple this
       
   943 	 * @var array
       
   944 	 */
       
   945 	var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
       
   946 
       
   947 	/**
       
   948 	 * Start the element output.
       
   949 	 *
       
   950 	 * @see Walker::start_el()
       
   951 	 * @since 2.1.0
       
   952 	 *
       
   953 	 * @param string $output   Passed by reference. Used to append additional content.
       
   954 	 * @param object $category Category data object.
       
   955 	 * @param int    $depth    Depth of category. Used for padding.
       
   956 	 * @param array  $args     Uses 'selected' and 'show_count' keys, if they exist. @see wp_dropdown_categories()
       
   957 	 */
       
   958 	function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
       
   959 		$pad = str_repeat('&nbsp;', $depth * 3);
       
   960 
       
   961 		$cat_name = apply_filters('list_cats', $category->name, $category);
       
   962 		$output .= "\t<option class=\"level-$depth\" value=\"".$category->term_id."\"";
       
   963 		if ( $category->term_id == $args['selected'] )
       
   964 			$output .= ' selected="selected"';
       
   965 		$output .= '>';
       
   966 		$output .= $pad.$cat_name;
       
   967 		if ( $args['show_count'] )
       
   968 			$output .= '&nbsp;&nbsp;('. $category->count .')';
       
   969 		$output .= "</option>\n";
       
   970 	}
       
   971 }
       
   972 
       
   973 //
       
   974 // Tags
       
   975 //
       
   976 
       
   977 /**
       
   978  * Retrieve the link to the tag.
       
   979  *
       
   980  * @since 2.3.0
       
   981  * @see get_term_link()
       
   982  *
       
   983  * @param int|object $tag Tag ID or object.
       
   984  * @return string Link on success, empty string if tag does not exist.
       
   985  */
       
   986 function get_tag_link( $tag ) {
       
   987 	if ( ! is_object( $tag ) )
       
   988 		$tag = (int) $tag;
       
   989 
       
   990 	$tag = get_term_link( $tag, 'post_tag' );
       
   991 
       
   992 	if ( is_wp_error( $tag ) )
       
   993 		return '';
       
   994 
       
   995 	return $tag;
       
   996 }
       
   997 
       
   998 /**
       
   999  * Retrieve the tags for a post.
       
  1000  *
       
  1001  * @since 2.3.0
       
  1002  * @uses apply_filters() Calls 'get_the_tags' filter on the list of post tags.
       
  1003  *
       
  1004  * @param int $id Post ID.
       
  1005  * @return array|bool Array of tag objects on success, false on failure.
       
  1006  */
       
  1007 function get_the_tags( $id = 0 ) {
       
  1008 	return apply_filters( 'get_the_tags', get_the_terms( $id, 'post_tag' ) );
       
  1009 }
       
  1010 
       
  1011 /**
       
  1012  * Retrieve the tags for a post formatted as a string.
       
  1013  *
       
  1014  * @since 2.3.0
       
  1015  * @uses apply_filters() Calls 'the_tags' filter on string list of tags.
       
  1016  *
       
  1017  * @param string $before Optional. Before tags.
       
  1018  * @param string $sep Optional. Between tags.
       
  1019  * @param string $after Optional. After tags.
       
  1020  * @param int $id Optional. Post ID. Defaults to the current post.
       
  1021  * @return string|bool|WP_Error A list of tags on success, false or WP_Error on failure.
       
  1022  */
       
  1023 function get_the_tag_list( $before = '', $sep = '', $after = '', $id = 0 ) {
       
  1024 	return apply_filters( 'the_tags', get_the_term_list( $id, 'post_tag', $before, $sep, $after ), $before, $sep, $after, $id );
       
  1025 }
       
  1026 
       
  1027 /**
       
  1028  * Retrieve the tags for a post.
       
  1029  *
       
  1030  * @since 2.3.0
       
  1031  *
       
  1032  * @param string $before Optional. Before list.
       
  1033  * @param string $sep Optional. Separate items using this.
       
  1034  * @param string $after Optional. After list.
       
  1035  */
       
  1036 function the_tags( $before = null, $sep = ', ', $after = '' ) {
       
  1037 	if ( null === $before )
       
  1038 		$before = __('Tags: ');
       
  1039 	echo get_the_tag_list($before, $sep, $after);
       
  1040 }
       
  1041 
       
  1042 /**
       
  1043  * Retrieve tag description.
       
  1044  *
       
  1045  * @since 2.8
       
  1046  *
       
  1047  * @param int $tag Optional. Tag ID. Will use global tag ID by default.
       
  1048  * @return string Tag description, available.
       
  1049  */
       
  1050 function tag_description( $tag = 0 ) {
       
  1051 	return term_description( $tag );
       
  1052 }
       
  1053 
       
  1054 /**
       
  1055  * Retrieve term description.
       
  1056  *
       
  1057  * @since 2.8
       
  1058  *
       
  1059  * @param int $term Optional. Term ID. Will use global term ID by default.
       
  1060  * @param string $taxonomy Optional taxonomy name. Defaults to 'post_tag'.
       
  1061  * @return string Term description, available.
       
  1062  */
       
  1063 function term_description( $term = 0, $taxonomy = 'post_tag' ) {
       
  1064 	if ( ! $term && ( is_tax() || is_tag() || is_category() ) ) {
       
  1065 		$term = get_queried_object();
       
  1066 		if ( $term ) {
       
  1067 			$taxonomy = $term->taxonomy;
       
  1068 			$term = $term->term_id;
       
  1069 		}
       
  1070 	}
       
  1071 	$description = get_term_field( 'description', $term, $taxonomy );
       
  1072 	return is_wp_error( $description ) ? '' : $description;
       
  1073 }
       
  1074 
       
  1075 /**
       
  1076  * Retrieve the terms of the taxonomy that are attached to the post.
       
  1077  *
       
  1078  * @since 2.5.0
       
  1079  *
       
  1080  * @param int|object $post Post ID or object.
       
  1081  * @param string $taxonomy Taxonomy name.
       
  1082  * @return array|bool|WP_Error Array of term objects on success, false or WP_Error on failure.
       
  1083  */
       
  1084 function get_the_terms( $post, $taxonomy ) {
       
  1085 	if ( ! $post = get_post( $post ) )
       
  1086 		return false;
       
  1087 
       
  1088 	$terms = get_object_term_cache( $post->ID, $taxonomy );
       
  1089 	if ( false === $terms ) {
       
  1090 		$terms = wp_get_object_terms( $post->ID, $taxonomy );
       
  1091 		wp_cache_add($post->ID, $terms, $taxonomy . '_relationships');
       
  1092 	}
       
  1093 
       
  1094 	$terms = apply_filters( 'get_the_terms', $terms, $post->ID, $taxonomy );
       
  1095 
       
  1096 	if ( empty( $terms ) )
       
  1097 		return false;
       
  1098 
       
  1099 	return $terms;
       
  1100 }
       
  1101 
       
  1102 /**
       
  1103  * Retrieve a post's terms as a list with specified format.
       
  1104  *
       
  1105  * @since 2.5.0
       
  1106  *
       
  1107  * @param int $id Post ID.
       
  1108  * @param string $taxonomy Taxonomy name.
       
  1109  * @param string $before Optional. Before list.
       
  1110  * @param string $sep Optional. Separate items using this.
       
  1111  * @param string $after Optional. After list.
       
  1112  * @return string|bool|WP_Error A list of terms on success, false or WP_Error on failure.
       
  1113  */
       
  1114 function get_the_term_list( $id, $taxonomy, $before = '', $sep = '', $after = '' ) {
       
  1115 	$terms = get_the_terms( $id, $taxonomy );
       
  1116 
       
  1117 	if ( is_wp_error( $terms ) )
       
  1118 		return $terms;
       
  1119 
       
  1120 	if ( empty( $terms ) )
       
  1121 		return false;
       
  1122 
       
  1123 	foreach ( $terms as $term ) {
       
  1124 		$link = get_term_link( $term, $taxonomy );
       
  1125 		if ( is_wp_error( $link ) )
       
  1126 			return $link;
       
  1127 		$term_links[] = '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a>';
       
  1128 	}
       
  1129 
       
  1130 	$term_links = apply_filters( "term_links-$taxonomy", $term_links );
       
  1131 
       
  1132 	return $before . join( $sep, $term_links ) . $after;
       
  1133 }
       
  1134 
       
  1135 /**
       
  1136  * Display the terms in a list.
       
  1137  *
       
  1138  * @since 2.5.0
       
  1139  *
       
  1140  * @param int $id Post ID.
       
  1141  * @param string $taxonomy Taxonomy name.
       
  1142  * @param string $before Optional. Before list.
       
  1143  * @param string $sep Optional. Separate items using this.
       
  1144  * @param string $after Optional. After list.
       
  1145  * @return null|bool False on WordPress error. Returns null when displaying.
       
  1146  */
       
  1147 function the_terms( $id, $taxonomy, $before = '', $sep = ', ', $after = '' ) {
       
  1148 	$term_list = get_the_term_list( $id, $taxonomy, $before, $sep, $after );
       
  1149 
       
  1150 	if ( is_wp_error( $term_list ) )
       
  1151 		return false;
       
  1152 
       
  1153 	echo apply_filters('the_terms', $term_list, $taxonomy, $before, $sep, $after);
       
  1154 }
       
  1155 
       
  1156 /**
       
  1157  * Check if the current post has any of given category.
       
  1158  *
       
  1159  * @since 3.1.0
       
  1160  *
       
  1161  * @param string|int|array $category Optional. The category name/term_id/slug or array of them to check for.
       
  1162  * @param int|object $post Optional. Post to check instead of the current post.
       
  1163  * @return bool True if the current post has any of the given categories (or any category, if no category specified).
       
  1164  */
       
  1165 function has_category( $category = '', $post = null ) {
       
  1166 	return has_term( $category, 'category', $post );
       
  1167 }
       
  1168 
       
  1169 /**
       
  1170  * Check if the current post has any of given tags.
       
  1171  *
       
  1172  * The given tags are checked against the post's tags' term_ids, names and slugs.
       
  1173  * Tags given as integers will only be checked against the post's tags' term_ids.
       
  1174  * If no tags are given, determines if post has any tags.
       
  1175  *
       
  1176  * 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)
       
  1177  * Prior to v2.7, this function could only be used in the WordPress Loop.
       
  1178  * As of 2.7, the function can be used anywhere if it is provided a post ID or post object.
       
  1179  *
       
  1180  * @since 2.6.0
       
  1181  *
       
  1182  * @param string|int|array $tag Optional. The tag name/term_id/slug or array of them to check for.
       
  1183  * @param int|object $post Optional. Post to check instead of the current post. (since 2.7.0)
       
  1184  * @return bool True if the current post has any of the given tags (or any tag, if no tag specified).
       
  1185  */
       
  1186 function has_tag( $tag = '', $post = null ) {
       
  1187 	return has_term( $tag, 'post_tag', $post );
       
  1188 }
       
  1189 
       
  1190 /**
       
  1191  * Check if the current post has any of given terms.
       
  1192  *
       
  1193  * The given terms are checked against the post's terms' term_ids, names and slugs.
       
  1194  * Terms given as integers will only be checked against the post's terms' term_ids.
       
  1195  * If no terms are given, determines if post has any terms.
       
  1196  *
       
  1197  * @since 3.1.0
       
  1198  *
       
  1199  * @param string|int|array $term Optional. The term name/term_id/slug or array of them to check for.
       
  1200  * @param string $taxonomy Taxonomy name
       
  1201  * @param int|object $post Optional. Post to check instead of the current post.
       
  1202  * @return bool True if the current post has any of the given tags (or any tag, if no tag specified).
       
  1203  */
       
  1204 function has_term( $term = '', $taxonomy = '', $post = null ) {
       
  1205 	$post = get_post($post);
       
  1206 
       
  1207 	if ( !$post )
       
  1208 		return false;
       
  1209 
       
  1210 	$r = is_object_in_term( $post->ID, $taxonomy, $term );
       
  1211 	if ( is_wp_error( $r ) )
       
  1212 		return false;
       
  1213 
       
  1214 	return $r;
       
  1215 }