wp_generate_tag_cloud()
云策文档标注
概述
wp_generate_tag_cloud() 函数用于根据提供的 WP_Term 对象数组生成标签云(热图)。它支持多种参数来自定义标签的显示方式,包括字体大小、数量、格式和排序等。
关键要点
- 函数接受两个参数:$tags(必需,WP_Term 对象数组)和 $args(可选,参数数组或字符串)。
- 参数 $args 包括 smallest、largest、unit、number、format、separator、orderby、order、filter、topic_count_text、topic_count_text_callback、topic_count_scale_callback 和 show_count,用于控制标签云的样式和行为。
- 返回值取决于 format 参数:可以是字符串(flat 或 list 格式)或数组(array 格式)。
- 函数内部使用 wp_parse_args() 合并默认参数,并应用多个过滤器(如 tag_cloud_sort、wp_generate_tag_cloud_data、wp_generate_tag_cloud)以允许自定义。
- 标签的字体大小基于计数通过 topic_count_scale_callback 回调函数进行缩放计算。
- 支持国际化,通过 topic_count_text 或 topic_count_text_callback 处理标签计数的复数文本。
代码示例
// 基本用法示例
$tags = get_tags(); // 获取标签数组
$args = array(
'smallest' => 12,
'largest' => 24,
'unit' => 'px',
'number' => 10,
'format' => 'flat',
'orderby' => 'count',
'order' => 'DESC',
'show_count' => true,
);
$tag_cloud = wp_generate_tag_cloud( $tags, $args );
echo $tag_cloud;注意事项
- 当 format 设置为 'array' 时,函数返回标签链接的数组,而不是 HTML 字符串。
- filter 参数默认为 1,启用 wp_generate_tag_cloud 过滤器,允许对输出进行最终修改。
- orderby 参数支持 'name' 或 'count',但可通过 tag_cloud_sort 过滤器进一步自定义排序。
- show_count 参数从 4.8.0 版本开始引入,用于控制是否显示标签计数。
原文内容
Generates a tag cloud (heatmap) from provided data.
Parameters
$tagsWP_Term[]required-
Array of WP_Term objects to generate the tag cloud for.
$argsstring|arrayoptional-
Array or string of arguments for generating a tag cloud.
smallestintSmallest font size used to display tags. Paired with the value of$unit, to determine CSS text size unit. Default 8 (pt).largestintLargest font size used to display tags. Paired with the value of$unit, to determine CSS text size unit. Default 22 (pt).unitstringCSS text size unit to use with the$smallestand$largestvalues. Accepts any valid CSS text size unit. Default'pt'.numberintThe number of tags to return. Accepts any positive integer or zero to return all.
Default 0.formatstringFormat to display the tag cloud in. Accepts'flat'(tags separated with spaces),'list'(tags displayed in an unordered list), or'array'(returns an array).
Default'flat'.separatorstringHTML or text to separate the tags. Default “n” (newline).orderbystringValue to order tags by. Accepts'name'or'count'.
Default'name'. The ‘tag_cloud_sort’ filter can also affect how tags are sorted.orderstringHow to order the tags. Accepts'ASC'(ascending),'DESC'(descending), or'RAND'(random). Default'ASC'.filterint|boolWhether to enable filtering of the final output via ‘wp_generate_tag_cloud’. Default 1.topic_count_textarrayNooped plural text from _n_noop() to supply to tag counts. Default null.topic_count_text_callbackcallableCallback used to generate nooped plural text for tag counts based on the count. Default null.topic_count_scale_callbackcallableCallback used to determine the tag count scaling value. Default default_topic_count_scale() .show_countbool|intWhether to display the tag counts. Default 0. Accepts 0, 1, or their bool equivalents.
Source
function wp_generate_tag_cloud( $tags, $args = '' ) {
$defaults = array(
'smallest' => 8,
'largest' => 22,
'unit' => 'pt',
'number' => 0,
'format' => 'flat',
'separator' => "n",
'orderby' => 'name',
'order' => 'ASC',
'topic_count_text' => null,
'topic_count_text_callback' => null,
'topic_count_scale_callback' => 'default_topic_count_scale',
'filter' => 1,
'show_count' => 0,
);
$args = wp_parse_args( $args, $defaults );
$return = ( 'array' === $args['format'] ) ? array() : '';
if ( empty( $tags ) ) {
return $return;
}
// Juggle topic counts.
if ( isset( $args['topic_count_text'] ) ) {
// First look for nooped plural support via topic_count_text.
$translate_nooped_plural = $args['topic_count_text'];
} elseif ( ! empty( $args['topic_count_text_callback'] ) ) {
// Look for the alternative callback style. Ignore the previous default.
if ( 'default_topic_count_text' === $args['topic_count_text_callback'] ) {
/* translators: %s: Number of items (tags). */
$translate_nooped_plural = _n_noop( '%s item', '%s items' );
} else {
$translate_nooped_plural = false;
}
} elseif ( isset( $args['single_text'] ) && isset( $args['multiple_text'] ) ) {
// If no callback exists, look for the old-style single_text and multiple_text arguments.
// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralSingular,WordPress.WP.I18n.NonSingularStringLiteralPlural
$translate_nooped_plural = _n_noop( $args['single_text'], $args['multiple_text'] );
} else {
// This is the default for when no callback, plural, or argument is passed in.
/* translators: %s: Number of items (tags). */
$translate_nooped_plural = _n_noop( '%s item', '%s items' );
}
/**
* Filters how the items in a tag cloud are sorted.
*
* @since 2.8.0
*
* @param WP_Term[] $tags Ordered array of terms.
* @param array $args An array of tag cloud arguments.
*/
$tags_sorted = apply_filters( 'tag_cloud_sort', $tags, $args );
if ( empty( $tags_sorted ) ) {
return $return;
}
if ( $tags_sorted !== $tags ) {
$tags = $tags_sorted;
unset( $tags_sorted );
} else {
if ( 'RAND' === $args['order'] ) {
shuffle( $tags );
} else {
// SQL cannot save you; this is a second (potentially different) sort on a subset of data.
if ( 'name' === $args['orderby'] ) {
uasort( $tags, '_wp_object_name_sort_cb' );
} else {
uasort( $tags, '_wp_object_count_sort_cb' );
}
if ( 'DESC' === $args['order'] ) {
$tags = array_reverse( $tags, true );
}
}
}
if ( $args['number'] > 0 ) {
$tags = array_slice( $tags, 0, $args['number'] );
}
$counts = array();
$real_counts = array(); // For the alt tag.
foreach ( (array) $tags as $key => $tag ) {
$real_counts[ $key ] = $tag->count;
$counts[ $key ] = call_user_func( $args['topic_count_scale_callback'], $tag->count );
}
$min_count = min( $counts );
$spread = max( $counts ) - $min_count;
if ( $spread <= 0 ) {
$spread = 1;
}
$font_spread = $args['largest'] - $args['smallest'];
if ( $font_spread < 0 ) {
$font_spread = 1;
}
$font_step = $font_spread / $spread;
$aria_label = false;
/*
* Determine whether to output an 'aria-label' attribute with the tag name and count.
* When tags have a different font size, they visually convey an important information
* that should be available to assistive technologies too. On the other hand, sometimes
* themes set up the Tag Cloud to display all tags with the same font size (setting
* the 'smallest' and 'largest' arguments to the same value).
* In order to always serve the same content to all users, the 'aria-label' gets printed out:
* - when tags have a different size
* - when the tag count is displayed (for example when users check the checkbox in the
* Tag Cloud widget), regardless of the tags font size
*/
if ( $args['show_count'] || 0 !== $font_spread ) {
$aria_label = true;
}
// Assemble the data that will be used to generate the tag cloud markup.
$tags_data = array();
foreach ( $tags as $key => $tag ) {
$tag_id = isset( $tag->id ) ? $tag->id : $key;
$count = $counts[ $key ];
$real_count = $real_counts[ $key ];
if ( $translate_nooped_plural ) {
$formatted_count = sprintf( translate_nooped_plural( $translate_nooped_plural, $real_count ), number_format_i18n( $real_count ) );
} else {
$formatted_count = call_user_func( $args['topic_count_text_callback'], $real_count, $tag, $args );
}
$tags_data[] = array(
'id' => $tag_id,
'url' => ( '#' !== $tag->link ) ? $tag->link : '#',
'role' => ( '#' !== $tag->link ) ? '' : ' role="button"',
'name' => $tag->name,
'formatted_count' => $formatted_count,
'slug' => $tag->slug,
'real_count' => $real_count,
'class' => 'tag-cloud-link tag-link-' . $tag_id,
'font_size' => $args['smallest'] + ( $count - $min_count ) * $font_step,
'aria_label' => $aria_label ? sprintf( ' aria-label="%1$s (%2$s)"', esc_attr( $tag->name ), esc_attr( $formatted_count ) ) : '',
'show_count' => $args['show_count'] ? '<span class="tag-link-count"> (' . $real_count . ')</span>' : '',
);
}
/**
* Filters the data used to generate the tag cloud.
*
* @since 4.3.0
*
* @param array[] $tags_data An array of term data arrays for terms used to generate the tag cloud.
*/
$tags_data = apply_filters( 'wp_generate_tag_cloud_data', $tags_data );
$a = array();
// Generate the output links array.
foreach ( $tags_data as $key => $tag_data ) {
$class = $tag_data['class'] . ' tag-link-position-' . ( $key + 1 );
$a[] = sprintf(
'<a href="%1$s"%2$s class="%3$s" style="font-size: %4$s;"%5$s>%6$s%7$s</a>',
esc_url( $tag_data['url'] ),
$tag_data['role'],
esc_attr( $class ),
esc_attr( str_replace( ',', '.', $tag_data['font_size'] ) . $args['unit'] ),
$tag_data['aria_label'],
esc_html( $tag_data['name'] ),
$tag_data['show_count']
);
}
switch ( $args['format'] ) {
case 'array':
$return =& $a;
break;
case 'list':
/*
* Force role="list", as some browsers (sic: Safari 10) don't expose to assistive
* technologies the default role when the list is styled with `list-style: none`.
* Note: this is redundant but doesn't harm.
*/
$return = "<ul class='wp-tag-cloud' role='list'>nt<li>";
$return .= implode( "</li>nt<li>", $a );
$return .= "</li>n</ul>n";
break;
default:
$return = implode( $args['separator'], $a );
break;
}
if ( $args['filter'] ) {
/**
* Filters the generated output of a tag cloud.
*
* The filter is only evaluated if a true value is passed
* to the $filter argument in wp_generate_tag_cloud().
*
* @since 2.3.0
*
* @see wp_generate_tag_cloud()
*
* @param string[]|string $return String containing the generated HTML tag cloud output
* or an array of tag links if the 'format' argument
* equals 'array'.
* @param WP_Term[] $tags An array of terms used in the tag cloud.
* @param array $args An array of wp_generate_tag_cloud() arguments.
*/
return apply_filters( 'wp_generate_tag_cloud', $return, $tags, $args );
} else {
return $return;
}
}
Hooks
- apply_filters( ‘tag_cloud_sort’, WP_Term[] $tags, array $args )
-
Filters how the items in a tag cloud are sorted.
- apply_filters( ‘wp_generate_tag_cloud’, string[]|string $return, WP_Term[] $tags, array $args )
-
Filters the generated output of a tag cloud.
- apply_filters( ‘wp_generate_tag_cloud_data’, array[] $tags_data )
-
Filters the data used to generate the tag cloud.