wp_generate_tag_cloud()WP 2.3.0

Processes the provided term (tag) data and returns the HTML code for the tag cloud.

Used By: wp_tag_cloud()

Returns

String|String[]. Tag cloud as a string or array, depending on the argument format.

Usage Template

$args = array(
	'smallest'  => 8,
	'largest'   => 22,
	'unit'      => 'pt',
	'number'    => 0,
	'format'    => 'flat',
	'separator' => '\n',
	'orderby'   => 'name',
	'order'     => 'ASC',
	'topic_count_text_callback'  => 'default_topic_count_text',
	'topic_count_scale_callback' => 'default_topic_count_scale',
	'filter'    => 1,
);

wp_generate_tag_cloud( $tags, $args );

Usage

<?php wp_generate_tag_cloud( $tags, $args ); ?>
$tags(array) (required)
Array of WP_Term objects to display in the "cloud". Based on this data, the appropriate text size for each tag will be created and the terms (tags) will be sorted.
$args(string/array)
Arguments that characterize the cloud.
Default: preset

Arguments of the $args parameter

smallest(int)
Text size for tags with fewer posts (units are specified in the unit parameter).
Default: 8
largest(int)
Text size for tags with more posts (units are specified in the unit parameter).
Default: 22
unit(string)
Units of measurement for the smallest and largest parameters. Can be any CSS size type: pt, px, em, %.
Default: 'pt'
number(int)
Maximum number of tags to be displayed in the list. If set to 0, all tags will be shown without limit.
format(string)

In what format to output the list. Can be:

  • flat - tags will be separated by the separator specified in the separator parameter;
  • list - UL list with CSS class 'wp-tag-cloud';
  • array - returns the tag cloud in an array for further processing in PHP.

Default: 'flat'

separator(string)
Text between tags.
Default: "\n"
orderby(string)
Sort tags by name (name) or number of posts (count).
Default: 'name'
order(string)

Order of sorting. Can be:

  • ASC - in order (1,2,3);
  • DESC - in reverse order (3,2,1);
  • RAND - random order (shuffle).

Default: 'ASC'

topic_count_text_callback(string)
The function that receives the number of posts and returns the text for the tag.
Default: 'default_topic_count_text'
topic_count_scale_callback(string)
Scaling function.
Default: 'default_topic_count_scale'
show_count(boolean)
Show the number of posts in the tag. Default 0. Can be: 0, 1 or true/false. Since WP 4.8.
filter(int)
Apply filter or not. If true, the result will be passed through the filter: wp_generate_tag_cloud.
Default: 1

Examples

0

#1 An example of what the function outputs

Let's get the categories and make a tag cloud out of them:

$terms = get_terms( [ 'taxonomy' => 'category' ] );

$cloud = wp_generate_tag_cloud( $terms, [
	'echo' => false,
] );

echo $cloud;

Outputs the following HTML:

<a href="" class="tag-cloud-link tag-link-0 tag-link-position-1" style="font-size: 8pt;" aria-label="Wordpress (0 items)">Wordpress</a>
<a href="" class="tag-cloud-link tag-link-1 tag-link-position-2" style="font-size: 18.070175438596pt;" aria-label="Author Features (16 items)">Author Features</a>
<a href="" class="tag-cloud-link tag-link-2 tag-link-position-3" style="font-size: 12.912280701754pt;" aria-label="Admin (3 elements)">Admin</a>
<a href="" class="tag-cloud-link tag-link-3 tag-link-position-4" style="font-size: 20.4444444444pt;" aria-label="Code (32 elements)">Code</a>
<a href="" class="tag-cloud-link tag-link-4 tag-link-position-5" style="font-size: 16.514619883041pt;" aria-label="Not WordPress (10 elements)">Not WordPress</a>
<a href="" class="tag-cloud-link tag-link-5 tag-link-position-6" style="font-size: 12.912280701754pt;" aria-label="Unnecessary (3 items)">Unnecessary</a>
<a href="" class="tag-cloud-link tag-link-6 tag-link-position-7" style="font-size: 14.959064327485pt;" aria-label="Optimization (6 elements)">Optimization</a>
<a href="" class="tag-cloud-link tag-link-7 tag-link-position-8" style="font-size: 22pt;" aria-label="Utilities (50 items)">Utilities</a>
<a href="" class="tag-cloud-link tag-link-8 tag-link-position-9" style="font-size: 18.315789473684pt;" aria-label="Useful little things (17 items)"> Useful little things</a>
<a href="" class="tag-cloud-link tag-link-9 tag-link-position-10" style="font-size: 18.643274853801pt;" aria-label="Miscellaneous (19 items)">Miscellaneous</a>
<a href="" class="tag-cloud-link tag-link-10 tag-link-position-11" style="font-size: 18.643274853801pt;" aria-label="Services and Hosting (19 items)">Services and Hosting</a>
<a href="" class="tag-cloud-link tag-link-11 tag-link-position-12" style="font-size: 14.385964912281pt;" aria-label="Theme WordPress (5 elements)">Theme WordPress</a>

Changelog

Since 2.3.0 Introduced.
Since 4.8.0 Added the show_count argument.

wp_generate_tag_cloud() code WP 6.9.1

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'>\n\t<li>";
			$return .= implode( "</li>\n\t<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;
	}
}