Back to Top

Customize your WordPress Tag Cloud

Previous Post:

Customize your WordPress Tag Cloud

Tag cloud, one of the most popular things in the blogging industry, is taken care of quite well in WordPress. What we got is a function that generates a customizable tag cloud with some configurable parameters such as font size, font unit, sorting order, etc. This function also provides some hooks for us end-users to modify the output to suit our needs.

In this article I would like to show you how to use the wp_tag_cloud function appropriately, and how to customize it beyond what it is already capable of. I hope you will find this article useful!

Using wp_tag_cloud()

Since its first appearance in WordPress 2.3.0, wp_tag_cloud()1 has become one of the most useful functions to WordPress users. Don’t let the name wp_tag_cloud() fools you, this function can be used to output any type of taxonomy archives, such as categories and custom taxonomies (ideally, it should be named wp_taxonomy_cloud()).

Choosing a font unit

If you have used this function before or read the codex article, you know that we can use either pt, px, em, or % as our measurement unit (you can read more about font unit in the Further Reading section.)

As of now, there is no conclusion of the debate about what is the best font unit to use, but I would recommend using em or % for wp_tag_cloud(). The very reason is, when you want to style your tag cloud you wouldn’t need to touch the code, sizing can be done simply via CSS.

For example when you set smallest to 1 and largest to 2 and unit to em, you are basically telling wp_tag_cloud() to output smallest tags as small as the container’s font size and largest tags double the container’s font size. You can then change the container’s font size later using only CSS, thus effectively increasing or decreasing tags’ font sizes without touching any code.

Output a custom taxonomy cloud

As I have said from the beginning, you can have a cloud of categories or custom taxonomies rather than post tags. This is done by changing the taxonomy parameter, like so:

  1. wp_tag_cloud(array('taxonomy' => 'category'));
  2. /* or */
  3. wp_tag_cloud(array('taxonomy' => 'registered custom taxonomies'));
  4. /* or */
  5. wp_tag_cloud(array('taxonomy' => array('post_tag','category'))); // added in WordPress 3.1
wp_tag_cloud(array('taxonomy' => 'category'));
/* or */
wp_tag_cloud(array('taxonomy' => 'registered custom taxonomies'));
/* or */
wp_tag_cloud(array('taxonomy' => array('post_tag','category'))); // added in WordPress 3.1

Please note that this allows you to output a cloud only, not a comprehensive list of a taxonomy, WordPress has different functions for that, such as: wp_list_categories()2.

Avoid code duplication

A tag cloud might be used in many locations, such as in sidebars, at the top of the Tag Archive page, etc. Such tag cloud should look the same in all locations and therefore should be handled by the same function.

To avoid writing a long and complicated wp_tag_cloud() function everywhere, it is recommended to use a custom function so that you can just edit wp_tag_cloud() in one place, and the changes will be reflected in all locations, like so:

  1. function bwp_wp_tag_cloud($echo = false)
  2. {
  3.     return wp_tag_cloud(array('orderby' => 'name', 'order' => 'ASC', 'echo' => $echo, 'unit' => 'em', 'smallest' => '1', 'largest' => '2'));
  4. }
function bwp_wp_tag_cloud($echo = false)
{
	return wp_tag_cloud(array('orderby' => 'name', 'order' => 'ASC', 'echo' => $echo, 'unit' => 'em', 'smallest' => '1', 'largest' => '2'));
}

Every time you need a tag cloud, you will call bwp_wp_tag_cloud() instead and when you need to edit the tag cloud, you will edit bwp_wp_tag_cloud() only, pretty neat!

Extend wp_tag_cloud()

Although wp_tag_cloud() is quite customizable with its default parameters, there are still some hard coded parts that you can not easily change. With a bit of PHP and courage, however, you can always extend its functionality ;).

Customize tag count

The first thing you will notice when using wp_tag_cloud() is that it doesn’t show the tag count next to the tag name, instead it shows the count inside the browser tooltips (the funny thing is that wp_list_categories(), a function also used to generate a tag list, allows you to show tag count next to name, but lacks the ability to show tags with different font sizes… so I guess a combination of both functions would be great).

Anyway, there’s no easy way to achieve our goal without rewriting wp_tag_cloud() from scratch. There are some hooks available for you to use but unfortunately they are set way after the desirable positions, making them (in my opinion) worthless :(.

Now the only (somewhat dirty) solution I can think of is to rewrite two functions: wp_tag_cloud() and wp_generate_tag_cloud() (both reside in wp-includes/category-template.php). You only have to copy their contents, modify what you need and then change the names, like so:

  1. function bwp_tag_cloud($args = '')
  2. {
  3.     // copy all the codes from wp_tag_cloud() here, except this line
  4.     // $return = wp_generate_tag_cloud( $tags, $args );
  5.     // change it to:
  6.     $return = bwp_generate_tag_cloud($tags, $args);
  7. }
  8.  
  9. function bwp_generate_tag_cloud($tags, $args = '')
  10. {
  11.     // copy all codes except this line:
  12.     // . "$unit;'>$tag_name</a>";
  13.     // change it to:
  14.     . "$unit;'>$tag_name</a> (" . $topic_count_text_callback($real_count) . ")";
  15. }
function bwp_tag_cloud($args = '')
{
	// copy all the codes from wp_tag_cloud() here, except this line
	// $return = wp_generate_tag_cloud( $tags, $args );
	// change it to:
	$return = bwp_generate_tag_cloud($tags, $args);
}

function bwp_generate_tag_cloud($tags, $args = '')
{
	// copy all codes except this line:
	// . "$unit;'>$tag_name</a>";
	// change it to:
	. "$unit;'>$tag_name</a> (" . $topic_count_text_callback($real_count) . ")";
}

Now when you want to show the tag cloud, instead of using wp_tag_cloud() you would use bwp_tag_cloud(), anything applies to wp_tag_cloud() will also apply to bwp_tag_cloud(). You now have the tag count staying next to tag name (it’s dirty I know, but it works ;)).

Advanced Tooltips

If you prefer having tag count stay inside tooltips but would like it to look better, you can use some Javascript tooltip libraries, such as:

Change tag count text

By default the tag count will be shown as “%s topics” with %s being the number of articles tagged with such tag (or topic). Luckily you can change this text by simply changing the topic_count_text_callback argument, like so:

  1. wp_tag_cloud(array('topic_count_text_callback' => 'my_count_text_callback'));
  2.  
  3. function my_count_text_callback($count)
  4. {
  5.     // change the below line to what you desire
  6.     return sprintf(_n('%s topic', '%s topics', $count), number_format_i18n($count));
  7. }
wp_tag_cloud(array('topic_count_text_callback' => 'my_count_text_callback'));

function my_count_text_callback($count)
{
	// change the below line to what you desire
	return sprintf(_n('%s topic', '%s topics', $count), number_format_i18n($count));
}

Please note the use of _n()3 and number_format_i18n()4, they are internationalization (i18n) functions that help you localize your string.

Make a colourful tag cloud

Using CSS

If you use the default wp_tag_cloud(), the output will automatically have CSS classes assigned to each tag, thus allowing you to give them any color you like, though not very practical, because those CSS classes share nothing in common, i.e. each tag has a different class, and they aren’t generated based on tag count, which is such a big disappointment.

Using custom functions

A count-based colored tag cloud is something many WordPress users are after, and such thing can be achieved using some custom functions.

We will be using the two custom functions described in the previous section plus a custom function to generate gradient colors5 like below:

  1. function generate_gradient($HexFrom, $HexTo, $ColorSteps)
  2. {
  3.     $FromRGB['r'] = hexdec(substr($HexFrom, 0, 2));
  4.     $FromRGB['g'] = hexdec(substr($HexFrom, 2, 2));
  5.     $FromRGB['b'] = hexdec(substr($HexFrom, 4, 2));
  6.  
  7.     $ToRGB['r'] = hexdec(substr($HexTo, 0, 2));
  8.     $ToRGB['g'] = hexdec(substr($HexTo, 2, 2));
  9.     $ToRGB['b'] = hexdec(substr($HexTo, 4, 2));
  10.  
  11.     $StepRGB['r'] = ($FromRGB['r'] - $ToRGB['r']) / ($ColorSteps - 1);
  12.     $StepRGB['g'] = ($FromRGB['g'] - $ToRGB['g']) / ($ColorSteps - 1);
  13.     $StepRGB['b'] = ($FromRGB['b'] - $ToRGB['b']) / ($ColorSteps - 1);
  14.  
  15.     $GradientColors = array();      
  16.  
  17.     for($i = 0; $i < $ColorSteps; $i++)
  18.     {
  19.         $RGB['r'] = floor($FromRGB['r'] - ($StepRGB['r'] * $i));
  20.         $RGB['g'] = floor($FromRGB['g'] - ($StepRGB['g'] * $i));
  21.         $RGB['b'] = floor($FromRGB['b'] - ($StepRGB['b'] * $i));  
  22.  
  23.         $HexRGB['r'] = sprintf('%02x', ($RGB['r']));
  24.         $HexRGB['g'] = sprintf('%02x', ($RGB['g']));
  25.         $HexRGB['b'] = sprintf('%02x', ($RGB['b']));
  26.  
  27.         $GradientColors[] = implode(NULL, $HexRGB);
  28.     }
  29.     return $GradientColors;
  30. }
function generate_gradient($HexFrom, $HexTo, $ColorSteps)
{
	$FromRGB['r'] = hexdec(substr($HexFrom, 0, 2));
	$FromRGB['g'] = hexdec(substr($HexFrom, 2, 2));
	$FromRGB['b'] = hexdec(substr($HexFrom, 4, 2));

	$ToRGB['r'] = hexdec(substr($HexTo, 0, 2));
	$ToRGB['g'] = hexdec(substr($HexTo, 2, 2));
	$ToRGB['b'] = hexdec(substr($HexTo, 4, 2));

	$StepRGB['r'] = ($FromRGB['r'] - $ToRGB['r']) / ($ColorSteps - 1);
	$StepRGB['g'] = ($FromRGB['g'] - $ToRGB['g']) / ($ColorSteps - 1);
	$StepRGB['b'] = ($FromRGB['b'] - $ToRGB['b']) / ($ColorSteps - 1);

	$GradientColors = array();      

	for($i = 0; $i < $ColorSteps; $i++)
	{
		$RGB['r'] = floor($FromRGB['r'] - ($StepRGB['r'] * $i));
		$RGB['g'] = floor($FromRGB['g'] - ($StepRGB['g'] * $i));
		$RGB['b'] = floor($FromRGB['b'] - ($StepRGB['b'] * $i));  

		$HexRGB['r'] = sprintf('%02x', ($RGB['r']));
		$HexRGB['g'] = sprintf('%02x', ($RGB['g']));
		$HexRGB['b'] = sprintf('%02x', ($RGB['b']));

		$GradientColors[] = implode(NULL, $HexRGB);
	}
	return $GradientColors;
}

To use the above function simply call it like this:

  1. $tag_gradients = generate_gradient("Start Color", "End Color", Color Steps);
$tag_gradients = generate_gradient("Start Color", "End Color", Color Steps);

The Start and End color must be in their hexadecimal forms, e.g. 000000 for black and CCCCCC for grey6. Color steps are actually the number of colors to generate for the gradient, for example if you are showing like 20 tags that have 5 sizes, you would set Color steps to 5 or smaller. $tag_gradients is an array that contain all generated colors.

While bwp_tag_cloud() remains the same, you will have to change bwp_generate_tag_cloud() to this (in this example we will use black for most used tags and grey for least used ones):

  1. function bwp_generate_tag_cloud($tags, $args = '')
  2. {
  3.     /* ... */
  4.  
  5.     foreach ( (array) $tags as $key => $tag ) {
  6.         $real_counts[ $key ] = $tag->count;
  7.         $counts[ $key ] = $topic_count_scale_callback($tag->count);
  8.     }
  9.  
  10.     // Generate color steps
  11.     $temp_counts = $real_counts;
  12.     sort($temp_counts);
  13.     $tag_gradients = array(); // color mapping array
  14.     $check_count = 0;
  15.     $color_steps = 0;
  16.     foreach ($temp_counts as $individual_count)
  17.     {
  18.         if ($check_count != $individual_count)
  19.         {
  20.             $check_count = $individual_count;
  21.             $color_steps++;
  22.             $tag_gradients[$individual_count] = '';
  23.         }
  24.     }
  25.     $temp_gradients = generate_gradient("cccccc", "000000", $color_steps);
  26.  
  27.     // Generate color mapping array for tags
  28.     $check_count = 0;
  29.     foreach ($tag_gradients as &$color)
  30.     {
  31.         $color = $temp_gradients[$check_count];
  32.         $check_count++;
  33.     }
  34.  
  35.     /* ... */
  36.  
  37.     $font_step = $font_spread / $spread;
  38.  
  39.     $a = array();
  40.  
  41.     $tag_color = 'cccccc';
  42.     foreach ( $tags as $key => $tag ) {
  43.         $count = $counts[ $key ];
  44.         $real_count = $real_counts[ $key ];
  45.         // assign color, if no color found, use previous color
  46.         $tag_color = (!empty($tag_gradients[$real_count])) ? $tag_gradients[$real_count] : $tag_color;
  47.         $tag_link = '#' != $tag->link ? esc_url( $tag->link ) : '#';
  48.         $tag_id = isset($tags[ $key ]->id) ? $tags[ $key ]->id : $key;
  49.         $tag_name = $tags[ $key ]->name;
  50.         $a[] = "<a href='$tag_link' class='tag-link-$tag_id' title='" . esc_attr( $topic_count_text_callback( $real_count ) ) . "' style='color: #" . $tag_color . "; font-size: " .
  51.             ( $smallest + ( ( $count - $min_count ) * $font_step ) )
  52.             . "$unit;'>$tag_name</a>";
  53.     }
  54.  
  55.     /* ... */
  56. }
function bwp_generate_tag_cloud($tags, $args = '')
{
	/* ... */

	foreach ( (array) $tags as $key => $tag ) {
		$real_counts[ $key ] = $tag->count;
		$counts[ $key ] = $topic_count_scale_callback($tag->count);
	}

	// Generate color steps
	$temp_counts = $real_counts;
	sort($temp_counts);
	$tag_gradients = array(); // color mapping array
	$check_count = 0;
	$color_steps = 0;
	foreach ($temp_counts as $individual_count)
	{
		if ($check_count != $individual_count)
		{
			$check_count = $individual_count;
			$color_steps++;
			$tag_gradients[$individual_count] = '';
		}
	}
	$temp_gradients = generate_gradient("cccccc", "000000", $color_steps);

	// Generate color mapping array for tags
	$check_count = 0;
	foreach ($tag_gradients as &$color)
	{
		$color = $temp_gradients[$check_count];
		$check_count++;
	}

	/* ... */

	$font_step = $font_spread / $spread;

	$a = array();

	$tag_color = 'cccccc';
	foreach ( $tags as $key => $tag ) {
		$count = $counts[ $key ];
		$real_count = $real_counts[ $key ];
		// assign color, if no color found, use previous color
		$tag_color = (!empty($tag_gradients[$real_count])) ? $tag_gradients[$real_count] : $tag_color;
		$tag_link = '#' != $tag->link ? esc_url( $tag->link ) : '#';
		$tag_id = isset($tags[ $key ]->id) ? $tags[ $key ]->id : $key;
		$tag_name = $tags[ $key ]->name;
		$a[] = "<a href='$tag_link' class='tag-link-$tag_id' title='" . esc_attr( $topic_count_text_callback( $real_count ) ) . "' style='color: #" . $tag_color . "; font-size: " .
			( $smallest + ( ( $count - $min_count ) * $font_step ) )
			. "$unit;'>$tag_name</a>";
	}

	/* ... */
}

/* ... */ is a block of codes that stay the same, from line 10 to line 33 are added codes, other highlighted lines are either added or modified. $tag_color is the variable that holds a tag’s color.

Now sit back and enjoy your colorful and nice looking tag cloud with most used tags in black and least used tags in grey! Other tags are colored based on their counts using the gradient generated between black and grey. If you would like to see a demo, you can browse to one of my tag archives: topic/customization/.

Highlight active tag

If you are, for example, viewing a specific tag archive and would like to highlight the tag name of that tag archive in a tag cloud, you can use the same approach above, like so:

  1.     /* ... */
  2.     foreach ( $tags as $key => $tag ) {
  3.         /* ... */
  4.         $tag_active = (is_tag($tag->slug)) ? 'active ' : '';
  5.         $a[] = "<a href='$tag_link' class='" . $tag_active . "tag-link-$tag_id' title='" . esc_attr( $topic_count_text_callback( $real_count ) ) . "' style='color: #" . $tag_color . "; font-size: " .
  6.             ( $smallest + ( ( $count - $min_count ) * $font_step ) )
  7.             . "$unit;'>$tag_name</a>";
  8.     }
  9.     /* ... */
	/* ... */
	foreach ( $tags as $key => $tag ) {
		/* ... */
		$tag_active = (is_tag($tag->slug)) ? 'active ' : '';
		$a[] = "<a href='$tag_link' class='" . $tag_active . "tag-link-$tag_id' title='" . esc_attr( $topic_count_text_callback( $real_count ) ) . "' style='color: #" . $tag_color . "; font-size: " .
			( $smallest + ( ( $count - $min_count ) * $font_step ) )
			. "$unit;'>$tag_name</a>";
	}
	/* ... */

Please note the use of is_tag()7 and the variable $tag_active, it will return ‘active’ if the checking tag is being viewed and empty if not. In your CSS file, a simple rule such as .active {text-decoration: underline;} will do the magic.

Using plugins

If you want a fancy looking tag cloud without touching any codes, there are some ready-made plugins out there and they are indeed powerful.

WP-Cumulus

WP-Cumulus allows you to display your site’s tags, categories or both using a Flash movie that rotates them in 3D. It works just like a regular tags cloud, but is more visually exciting.

Please note that this plugin also supports gradient for coloring tag names.

WP Cumulus

WP Cumulus

Better Tag Cloud

This plugin provides full control over your tag cloud, although it is not that cool compared to WP-Cumulus, it is very customizable and easy to use.

Better Tag Cloud

Better Tag Cloud

Rounded Tag Cloud

A rather simple plugin that uses the same function with the standard tag cloud widget. It only formats the look of tags so that it has different background and rounded corner.

Rounded Tag Cloud

Rounded Tag Cloud

Further Reading

  1. http://www.w3.org/Style/Examples/007/units
  2. http://css-tricks.com/css-font-size/

References

  1. http://codex.wordpress.org/Function_Reference/wp_tag_cl ... _tag_cloud []
  2. http://codex.wordpress.org/Template_Tags/wp_list_catego ... categories []
  3. http://codex.wordpress.org/I18n_for_WordPress_Developer ... Developers []
  4. http://phpxref.ftwr.co.uk/wordpress/_functions/number_f ... _i18n.html []
  5. http://www.geekpedia.com/code163_Generate-Gradient-With ... n-PHP.html []
  6. http://www.w3schools.com/css/css_colors.asp []
  7. http://codex.wordpress.org/Function_Reference/is_tag []
Elegant Themes - Designed with Modest Elegance
Print Article Trackback Trackback to this Article   Subscribe to Comments RSS Subscribe to Comments RSS

10 Opinions for Customize your WordPress Tag Cloud (2 Trackbacks)

  1. User's Gravatar
    1
    kim April 4, 2011 at 3:00 pm – Permalink

    If we use inline style to color tags like that we won’t be able to change the color using css anymore??

    • User's Gravatar
      2
      OddOneOut April 4, 2011 at 5:32 pm – Permalink

      Adding a lot of CSS classes might not be ideal either. I think you can change the current tag using Javascript, like what I did here: http://betterwp.net/topic/plugin-alternatives/. Something as simple as this:

      1.     jQuery('.archive-nav-tag a').hover(    
      2.         function(){
      3.             color = jQuery(this).css('color');
      4.             jQuery(this).css('color', '#1a2529');
      5.         },
      6.         function(){
      7.             jQuery(this).css('color', color);
      8.         }
      9.     );
      	jQuery('.archive-nav-tag a').hover(		
      		function(){
      			color = jQuery(this).css('color');
      			jQuery(this).css('color', '#1a2529');
      		},
      		function(){
      			jQuery(this).css('color', color);
      		}
      	);

      will work ;).

  2. User's Gravatar
    5
    Mahesh Mohan July 7, 2012 at 11:16 pm – Permalink

    Can you please tell me how to filter tags?

    The code <?php wp_tag_cloud(”); ?> shows all the tags in the blog but what if I want to show only select tags?

    • User's Gravatar
      6
      OddOneOut July 8, 2012 at 9:55 pm – Permalink

      You will need to use custom functions to achieve that.

  3. User's Gravatar
    7
    Maxwell December 30, 2012 at 10:31 pm – Permalink

    Hi all!
    How to get the $real_count
    need a counter that shows how many records are in the tags

    • User's Gravatar
      8
      OddOneOut January 2, 2013 at 12:37 am – Permalink

      Where do you want to use that $real_count variable?

      • User's Gravatar
        9
        Maxwell January 10, 2013 at 7:25 pm – Permalink

        Example
        simpletag – 14, simpletag – 5, simpletag – 3

  4. User's Gravatar
    10
    Olga May 20, 2013 at 9:36 am – Permalink

    Thank you! Very useful article for me, initially found in russian, but there is much more detail

  1. Выделение активного тега в облаке « Мысли Вслух « ЛД "Glavart".Cоздание сайта Киев.Разработка сайта Киев.Создание интернет-магазина

    [...] таблицу стилей – должно работать! Спасибо за статью betterwp.net. Информация оказалась вам полезна?- Поделитесь [...]

  2. Pretty (er) default wordpress tagcloud | Blog

    [...] also another really smart person over at betterWP.net who had a really good argument about using ‘em’ as the unit size. Read the part under the heading ‘Choosing a Font Unit’. Pretty clever. It didn’t [...]

Speak Up Your Mind!

An asterisk (*) indicates a required field and must be filled.




  • Web page and e-mail addresses turn into links automatically.
  • Wrap codes in: <code lang=""></code> or <pre lang="" extra="">
  • Lines and paragraphs break automatically.

Next Post: