How To Customize WordPress Tag Cloud Without a Plugin

For a WordPress blog, a Tag cloud displays a list of tags. Tags are usually single words, and the importance of each Tag is shown with different font size. The size of each Tag is determined by how many times that particular Tag has been assigned to posts. Tags are links that lead to a list of posts associated with each Tag. The WordPress Tag cloud is a widget that displays all popular tags in a convenient layout. More…

Tag Cloud Benefits

Like any WordPress Widget, and depending on the flexibility of your theme, Tag cloud widget can be used anywhere in your WordPress Website. Your readers can search different topics based on Tags instead of categories. Also Tags help your Website gain higher ranking in Search Engines by using different keywords related to the post. Tags are text links, rich in keywords, that are indexed by search engines. A Tag cloud would help your Website with more search queries. The more you use the same tags, the more they will grow in importance for your visitors and search engines. It is important to keep tags relevant to the post. Around 5 tags per post is good enough.

Default WordPress Tag Cloud

If you are using the standard version of the WordPress Tag cloud, you may dislike how it looks. Many people, including myself, are not happy with just using the default WordPress Tag Cloud widget without being able to modify it. We want to have control. This is where this tutorial helps!

Custom Tag Cloud

My version of the Tag cloud lets you customize it to your liking. Also in my code you have additional controls that are not part of the default WordPress Tag cloud. The custom Tag cloud on the right sidebar of this blog is generated by the code shown below.

Prerequisite: This tutorial assumes that your WordPress theme already supports widgets. To find out, check your theme´s documentation. Also it should be mentioned in your WordPress dashboard. Your theme must support widgets, for this code to work.

What about a Plugin? Yes, there are plugins that customize WordPress Tag Clouds, such as Configurable Tag Cloud and Better Tag Cloud being the most popular. But haven´t you read my previous post about the disadvantages of going crazy adding plugins to your theme?

Advantages of My Custom Tag Cloud Code

These are the main advantages of adding my code:

  1. No need to install an additional plugin for your WordPress Website.
  2. The code is added to your theme´s functions.php file. Your WordPress core files are not modified.
  3. You can change any default parameter to your liking: (smallest, largest, unit, number, format, separator, order, etc). More details.
  4. In addition: My custom Tag cloud code allows you to:
    • Limit the Tags in the cloud based on their weight (i.e. number of posts they are attached to). For example, you can exclude tags that have more than or less than some defined number of posts.
    • Change The Tag color based on its weight. The Tag weight is determined by the number of posts attached to each Tag. For example, Tags with less weight will have a different color than Tags with more weight.

WordPress Custom Tag Cloud Code

This is my version of the custom Tag cloud code. Open the functions.php file located in your theme´s folder and add (copy and paste) the following three functions. This code is tested to work for the current WordPress version. Sorry for the long code!
Note: If the vertical scroll bar is shown, you need to scroll all the way down to see the horizontal bar.

To set your own parameters, search the code for: ***MODIFY TO WHAT YOU LIKE***

/***** Custom Tag Cloud Code without the need of a Plugin. 
       Tested up to WordPress version 3.1.2 *****/

/** Function that generates Tag colors based on their weight (number of posts per Tag)
If nothing gets passed in to the function for $min_color and $max_color, it skips the function
and uses the defined link color in the CSS.  If only one color is passed, it is used for both.
Function is based on Version 5.2 of the Configurable Tag Cloud plugin **/

function color_weight($weight, $min_color, $max_color) {
	if ($min_color == "" && $max_color == "")

	if ($min_color == "") {
		$color = $max_color;
		return $color;
	if ($max_color == "") {
		$color = $min_color;
		return $color;
	if ($weight) {
		$weight = $weight/100;

		//hack to handle CSS shorthand color definitions (i.e., #000 instead of #000000)
		//strlen — Get string length (
		if (strlen($min_color) == 4) {
			//substr — Return part of a string (
			$r = substr($min_color, 1, 1);
			$g = substr($min_color, 2, 1);
			$b = substr($min_color, 3, 1);

			$min_color = "#$r$r$g$g$b$b";
		if (strlen($max_color) == 4) {
			$r = substr($max_color, 1, 1);
			$g = substr($max_color, 2, 1);
			$b = substr($max_color, 3, 1);

			$max_color = "#$r$r$g$g$b$b";
		//hexdec — Hexadecimal to decimal (
		$minr = hexdec(substr($min_color, 1, 2));
		$ming = hexdec(substr($min_color, 3, 2));
		$minb = hexdec(substr($min_color, 5, 2));

		$maxr = hexdec(substr($max_color, 1, 2));
		$maxg = hexdec(substr($max_color, 3, 2));
		$maxb = hexdec(substr($max_color, 5, 2));

		//intval — Get the integer value (
		$r = dechex(intval((($maxr - $minr) * $weight) + $minr));
		$g = dechex(intval((($maxg - $ming) * $weight) + $ming));
		$b = dechex(intval((($maxb - $minb) * $weight) + $minb));

		if (strlen($r) == 1) $r = "0".$r;
		if (strlen($g) == 1) $g = "0".$g;
		if (strlen($b) == 1) $b = "0".$b;

		$color = "#$r$g$b";
		$color = substr($color,0,7);
		return $color;

/*** Function that Generates an HTML string that makes the Tag Cloud ****/
//See Reference:
//This function is similar as 'wp_generate_tag_cloud()' located in: 'wp-includes/category-template.php'
//Major difference: This function COLORS the Tags in the cloud based on their 
//weight (number of posts attached to the Tag) as shown in the short code. 
function bac_generate_tag_cloud( $tags, $args = '' ) {
	global $wp_rewrite;
	$defaults = array( //***KEEP THE DEFAULTS DON'T TOUCH.***
		'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,
	//!isset — Determine if a variable is NOT set or is NULL (
	if ( !isset( $args['topic_count_text_callback'] ) && isset( $args['single_text'] ) && isset( $args['multiple_text'] ) ) {
		//var_export — returns a parsable string representation of a variable (
		$body = 'return sprintf (
			_n(' . var_export($args['single_text'], true) . ', ' . var_export($args['multiple_text'], true) . ', $count),
			number_format_i18n( $count ));';
		//create_function — Create an anonymousfunction (
		$args['topic_count_text_callback'] = create_function('$count', $body);
	$args = wp_parse_args( $args, $defaults );
	//extract — Import variables into the current symbol table from an array (
	extract( $args );

	if ( empty( $tags ) )

	$tags_sorted = apply_filters( 'tag_cloud_sort', $tags, $args );
	if ( $tags_sorted != $tags  ) { // the tags have been sorted by a plugin
		$tags = $tags_sorted;
	} else {
		if ( 'RAND' == $order ) {
		} else {
			// SQL cannot save you; this is a second (potentially different) sort on a subset of data.
			if ( 'name' == $orderby )
				uasort( $tags, create_function('$a, $b', 'return strnatcasecmp($a->name, $b->name);') );
				uasort( $tags, create_function('$a, $b', 'return ($a->count > $b->count);') );

			if ( 'DESC' == $order )
				$tags = array_reverse( $tags, true );
	if ( $number > 0 )
		$tags = array_slice($tags, 0, $number);

	$counts = array();
	$real_counts = array(); // For the alt Tag
	foreach ( (array) $tags as $key => $tag ) {
		$real_counts[ $key ] = $tag->count;
		$counts[ $key ] = $topic_count_scale_callback($tag->count);
	$min_count = min( $counts );
	$spread = max( $counts ) - $min_count;
	if ( $spread <= 0 )
		$spread = 1;
	$font_spread = $largest - $smallest;
	if ( $font_spread < 0 )
		$font_spread = 1;
	$font_step = $font_spread / $spread;

	$a = array();

	foreach ( $tags as $key => $tag ) {
		$count = $counts[ $key ];
		$real_count = $real_counts[ $key ];
		$tag_link = '#' != $tag->link ? esc_url( $tag->link ) : '#';
		$tag_id = isset($tags[ $key ]->id) ? $tags[ $key ]->id : $key;
		$tag_name = $tags[ $key ]->name;
		/* Short code that changes the Tag color based on its weight (how many posts are attached to each Tag.) */
		//Define Variable: Beginning color for Tag. format" "#xxx" or "#xxxxxx" where x = [0-9,a-f]
		//If both variables are not defined it uses the Tag color as defined in the CSS document.
		$min_color = "#5679B9"; //***MODIFY TO WHAT YOU LIKE***
		//Define Variable: Ending color for Tag. format" "#xxx or "#xxxxxx"
		$max_color = "#AF1410"; //***MODIFY TO WHAT YOU LIKE***
		if ($largest == $smallest)
			$tag_weight = $largest;
			$tag_weight = ($smallest+(($count-$min_count)*$font_step));
		$diff = $largest-$smallest;
		if ($diff <= 0)
			$diff = 1;
		//round — Rounds a float (	
		$color_weight = round(99*($tag_weight-$smallest)/($diff)+1);
		//this is the color_weight() functions defined above. 
		$tag_color = color_weight($color_weight, $min_color, $max_color);
		//Modified to include Tag Link color.
		//call_user_func — Call a user function given by the first parameter ( 
		$a[] = "<a href='$tag_link' class='tag-link-$tag_id' title='" . esc_attr( call_user_func( $topic_count_text_callback, $real_count ) ) . "' style='font-size: " . 
			( $smallest + ( ( $count - $min_count ) * $font_step ) )
			. "$unit;  color: $tag_color; background-color: inherit;'>$tag_name</a>"; //background-color is added for validation purposes.
		/*** End of short code ***/		
	switch ( $format ) :
	case 'array' :
		$return =& $a;
	case 'list' :
		$return = "<ul class='wp-tag-cloud'>\n\t<li>";
		//join — Alias of implode() (
		$return .= join( "</li>\n\t<li>", $a );
		$return .= "</li>\n</ul>\n";
	default :
		$return = join( $separator, $a );
		//Function to create a new filter hook (
		return apply_filters( 'bac_generate_tag_cloud', $return, $tags, $args );

/*** Function that Displays the Tag Cloud ****/
//See Reference: 
//This function is similar as 'wp_tag_cloud()' located in: 'wp-includes/category-template.php'
//Major difference: This function excludes Tags in the cloud based on their weight as shown in the short code. 
function bac_tag_cloud($args) {

$defaults = array( // ***MODIFY TO WHAT YOU LIKE***

	'smallest' => 12,   //The smallest Tag (lowest count) is shown at size 12
	'largest' => 30,    //The largest Tag (highest count) is shown at size 30 
	'unit' => 'px',     //Unit of measure for the smallest and largest values. Can be any CSS value (pt, px, em, %). 
	'number' => 50,     //set how many tags to show (default is 45 tags in the Tag cloud list).
	'format' => 'flat', // Format of the cloud display (flat, list, array) 
	'separator' => "\n", //The text/space between tags. 
	'orderby' => 'name', //argument will accept 'name' or 'count' and defaults to 'name'.
	'order' => 'ASC',   //sort order, defaults to 'ASC' and can be 'DESC'
	'exclude' => '',   //Exclude a specific Tag by its Tag ID separated by commas.
	'include' =>'',   //Include a specific Tag by Tag ID separated by commas. Use 'exclude' or 'include', but not both.
	'link' => 'view',  //Set link to allow edit of a particular Tag.
	'taxonomy' => 'post_tag', //Taxonomy or array of taxonomies to use in generating the cloud. 
	'echo' => true //DO NOT TOUCH THIS.
); //***End Of MODIFY SECTION***

//wp_parse_args() is a generic utility for merging together an array of arguments and an array of default values. 
$args = wp_parse_args( $args, $defaults );
//Retrieve the terms in taxonomy or list of taxonomies. 
/*  ;*/
// Always query top tags
$tags = get_terms( $args['taxonomy'], array_merge( $args, array( 'orderby' => 'count', 'order' => 'DESC' ) ) ); 

//If there are no tags
if ( empty( $tags ))
	return; //ends execution of the current function

/***** Short Code that gives the user the option not to display Tags in the Cloud 
based on the Tag's weight (number of posts attached to the Tag.)  *****/

//Minimum number of posts per tags. ***MODIFY TO WHAT YOU LIKE***
$min_num = 1;  // Tags with less than this number of posts will not be displayed.

//maximum number of posts per tags. ***MODIFY TO WHAT YOU LIKE***
$max_num = 65; //Tags with more than this number of posts will not be displayed.

foreach($tags as $key => $tag)
	{	//If the post count of Tag is outside the range
		if($tag->count < $min_num || $tag->count > $max_num)
			/*unset()-destroy a single element of an array -*/ 
/*** End of short code ***/

foreach ( $tags as $key => $tag ) {
		if ( 'edit' == $args['link'] )
			//Displays a link to edit the current Tag, if the user is logged in and allowed to edit the Tag.
			$link = get_edit_tag_link( $tag -> term_id, $args['taxonomy'] );
			//Returns permalink for a taxonomy term archive. 
			$link = get_term_link( intval($tag -> term_id), $args['taxonomy'] );
		//Check whether variable is a WordPress Error. 
		if ( is_wp_error( $link ) )
			return false;

	$tags[ $key ] -> link = $link;
	$tags[ $key ] -> id = $tag -> term_id;
//Generates a Tag cloud (heatmap) from provided data. Located at: 
$return = bac_generate_tag_cloud( $tags, $args ); // Here is where those top tags get sorted according to $args

//Function to create a new filter hook.
$return = apply_filters( 'bac_tag_cloud', $return, $args );

if ( 'array' == $args['format'] || empty($args['echo']) )
	return $return;

echo $return;
//Hooks a function to a specific filter action.
add_filter('wp_tag_cloud', 'bac_tag_cloud');

Styling the Custom Tag Cloud

Finally we need to style the custom Tag cloud code with CSS. The following CSS code is what I used for this blog. The code should be part of your theme´s CSS file (usually called style.css). You probably already have a CSS code in place for the cloud and this step might not be necessary.

/* Styling Custom Tag Cloud Widget by BOUTROS ABICHEDID */

#sidebar ul li.widget_tag_cloud{
    padding:0 0 30px 0; 
#sidebar ul li.widget_tag_cloud a{
    padding:0 0 0 15px;
#sidebar ul li.widget_tag_cloud a:hover{
    text-decoration: none;
    color:#695321 !important; 
    background-color: inherit;


You now can customize your Tag cloud without the need of a plugin and without modifying your WordPress core files. In addition, you have more control of what tags to show and what color to display based on their weight. If you have any questions or anything else to say, make sure to leave a comment. Thank you for reading!


  1. Function Reference « WordPress Codex
  2. wp_tag_cloud() Function
  3. Taxonomies
  4. WordPress Widgets
  5. Is Tag Cloud useful, does it give SEO boost, …
  6. Tag Clouds and SEO

If you enjoyed this post, please consider: linking back to it, subscribing by email to future posts, or subscribing to the RSS feed to have new articles delivered to your feed reader. Thanks!

About the Author |
Boutros is a professional Drupal & WordPress developer, Web developer, Web designer, Software Engineer and Blogger. He strives for pixel perfect design, clean robust code, and user-friendly interface. If you have a project in mind and like his work, feel free to contact him. Connect with Boutros on Twitter, and LinkedIn.
Visit Boutros AbiChedid Website.

42 Responses to “How To Customize WordPress Tag Cloud Without a Plugin”

  1. conielben says:

    could I write many wordpress tag cloud for keywords?

    for example, I want to create a tag page like, which lists all wordpress tags containing “wordpress” or “tag”.

    If it is possible, could you please tell me the details how to do.

    Thanks very much.

  2. mohammad says:

    Thanks for the nice tutorial.

  3. zz says:

    Well… this doesn’t work for me. it does not change the tag sizes in the sidebar…. any idea what can i do ?

    • Hi,
      You have to give me more information. What theme you are using? (link?).
      Does the color change in the tag cloud?
      The Tag font and color change depending on its weight (i.e. how many posts are attached to it).
      The tag font size increases depending how many posts are attached to each tag. If all your tags have 1 post attached to each one of them then
      the font size (and color) will be the same.
      If you like, you can change the color on lines 145 and 148 of the code. And for the font size, on lines 199 and 200 of the code.
      For my blog, I have 3 different themes and the code works on all of them.

  4. David H says:

    This is a great article, great code. In the Admin it seems important enough to DESCRIBE a tag in text that they even provide a field just for storing that text. So, where is it used?

    And even your code seems to skip over this value. How can your code be modified to also pull up the DESCRIPTION for a tag for even MORE SEO friendly effect?

    • Hi David H.,

      You are right, the Tag description is optional in the dashboard and most themes don’t show it by default, because most users don’t fill out the description. I agree, it is better to include a Tag description for SEO purposes especially if the meaning/purpose of the tag is not clear.

      Currently the tag cloud has the count as a title attribute of each tag link (hover your mouse over each tag link to see the count).
      But if you would like to show the tag description and the count in the title attribute of each tag link. Here is what you need to do:

      Remove the statement on lines 167, 168 and 169 and Replace it with this statement:

      //call_user_func — Call a user function given by the first parameter ( 
      $a[] = "<a href='$tag_link' class='tag-link-$tag_id' title='".$tag->description.' ('.esc_attr( call_user_func( $topic_count_text_callback, $real_count ) ) .')'. "' style='font-size: " . 
      			( $smallest + ( ( $count - $min_count ) * $font_step ) )
      			. "$unit;  color: $tag_color; background-color: inherit;'>$tag_name</a>"; //background-color is added for validation purposes.
      /*** End of short code ***/	

      When you hover over a Tag link in the Tag Cloud, the output of the code will be.
      1. If there is a typed Tag description in the dashboard output is: “tag description (count)”
      2. If the description is blank, the output is: ” (count)”

      This will take care of both scenarios, without an If statement.
      Hope this helps.

  5. Sergiu says:

    Brilliant piece of code, long or not!


  6. Toni says:

    Thanks for this. Do you have any clues on what to do if your tags and tag cloud isn’t linking properly? Meaning it won’t pull up all the posts related to a particular tag.

    • Hi Toni,

      I am not sure why the tags in the cloud are not pulling all the links. My code should. I never had this problem before, so I am not sure what the problem is here?


  7. RefWoofepek says:

    very interesting, thanks.

  8. Richard Thai says:

    Hi there Boutros,

    Your code work like a charm! I already get the ‘list’ view now.
    but I need to show number of post too, like this site:

    Where in your code I need to change to do this?

    Actually I’ve found some infos about this here:
    But I don’t feel like add another set of code, and I don’t no how too…


    • Hi Richard,

      To change the Tag cloud to a list (I know you figured this one, but meant for others), Replace line 203 ('format' => 'flat',) with this:
      'format' => 'list',

      Currently the tag cloud has the count as a title attribute of each tag link (hover your mouse over each tag link to see the count).
      But if you also like to show the number of posts beside each tag link:

      Remove the statement on lines 167, 168 and 169 and Replace it with this (line numbers might be different in your case depending on the font size):

      //call_user_func — Call a user function given by the first parameter ( 
      $a[] = "<a href='$tag_link' class='tag-link-$tag_id' title='" . esc_attr( call_user_func( $topic_count_text_callback, $real_count ) ) . "' style='font-size: " . 
      ( $smallest + ( ( $count - $min_count ) * $font_step ) )
      . "$unit;  color: $tag_color; background-color: inherit;'>$tag_name</code></a> " //background-color is added for validation purposes.
      . '('.$tag->count.')'; 
      /*** End of short code ***/	

      Hope this helps.

  9. Melanie says:

    Hi there Boutros,
    I’m not sure i quite understand. Do I still need to drag the cloud tag widget across to my right side bar in wordpress or does the code tell it where to go on my page?

    • Hi Melanie,

      The short answer: Yes you do, when you drag the Tag cloud widget to your sidebar that’s how you activate it. Otherwise the tag Cloud will not show in your Website (since it is inactive).

      The long answer for anybody who is still confused…. Here are the steps.

      1. First make sure that your theme support widgets. The easiest way to know that, login to your WP dashboard.
      2. Go to “Appearance -> Widgets” and check if you have the ‘Tag Cloud’ widget as part of your available Widgets.
      3. If you do, then activate it by dragging it to the sidebar1 (or to the footer depending on the theme). Then copy and paste the code above to your theme’s ‘functions.php’ file and follow the instructions in the code if you want to modify any parameters. Save the file and the tag Cloud should show up in your Website.
      4.If you don’t have the Tag Cloud widget in your available widgets. Then stop, since your theme has no support for the Tag cloud widget (probably for widgets in general). Choose another theme ….This code will not work.

      From looking at your Website, your theme support widgets (Most Recent posts, Recent comments, Topics, all located on the right side of the Webpage)
      Hope this helps.

      • Melanie says:

        Thanks a lot Boutros, that is really clear now….only problem is i can’t find my themes ‘functions.php file’. Should this be easy to find somewhere in the dashboard or down the left hand side?

        • Hi Mel,

          You could use an FTP program to download the file locally from to the server and then use an editor of your choice to update the functions.php file (like Notepad, DreamWearver, Notepad++) and then use the FTP program to upload it to the server.
          On the server the file is in the folder of whatever theme you have where you installed your WP blog.
          (Themes are located …/wp-content/themes/”your theme’s name folder”/functions.php)

          Or you could login to your WP dashboard, go to “Appearance -> editor” then on the right side of the dashboard you see the ‘functions.php’ file,
          you could edit it from there (Make sure you select your theme, if you have several themes in your dashboard).

          Hope this helps.

  10. Mike Saky says:

    Hi, that is absolutely fantastic, but I use wordpress 3.1.2 and I can not log-in to wordpress admin. If I remove your functions about tags – no problems.
    Can you make update or give me some advice?

    • Hi Mike,

      I just did a Manual upgrade to WP version 3.1.2 and everything works fine and I can access the admin area and the tag cloud still works as you can see in this blog. I don’t know what happened in your case. If you did a manual install it is important to delete the files and not overwrite them. One time I did a manual install where I just overwrote the files and I could not login to the admin area.
      This is What WordPress says:

      “Updating Manually
      1.Before you update anything, make sure you have backup copies of any files you may have modified such as index.php.
      2.Delete your old WordPress files, saving ones you’ve modified.
      3.Upload the new files.
      4.Point your browser to /wp-admin/upgrade.php.

      I think in your case there is another reason for your problem other than the tag cloud code, it is probably conflicting with some plugin, or there is some other unknown reason to me.

      When you find out the cause, please share here so that others can learn.


  11. pamajoro says:


    Thanks for the code. Looks great too.

    I was wondering if there was a shortcode that can be used with this script to show on a page or post rather than just in a widget.

    Thanks again,

    • Hi Pamajoro,

      Thank you for your feedback.

      There are probably 90% of the WP themes out there that natively support widgets/dynamic_sidebar() function. The other 10% are probably old themes anyway (my statistics are a guess but it is safe to say that the majority of the themes natively support widgets)
      The idea here is to use the built-in core capabilities of the WordPress code (dynamic_sidebar() function) and not reinvanting the wheel and adding code to your theme unnecessarily. Depending on the theme, widgets are either located on the right side or bottom of the page or it could also be in both. This is where widgets are. I am not sure what’s the logic behind having the Tag cloud on a page or post? The tag Cloud shows up in every page and every post but on the side (like the case of this blog) or it could be at the footer in other themes.

      Let’s say your theme does not support widgets. Usually to add the shortcode you add this wherever you want to add the tag cloud.

      < ? php if(function_exists('bac_tag_cloud')) { bac_tag_cloud(); } ?>

      In this case the tag Cloud will be generated but with errors. Here it will not work because I have 3 separate functions (bac_tag_cloud(), bac_generate_tag_cloud() and color_weight()). They need to be merged into one function (more work needs to be done) and then I think that the Tag cloud will work without a Widget (I have not tested it)

      By the way have you tried my Tag Cloud code in your theme? Did it work for you? Do you have widget support in your theme?


  12. prahalad says:

    I have done this, but how to display the tag cloud in the sidebar.. what shortcode etc. I have to use to get the TagCloud…

    • Hi prahalad,

      Once you add (copy and paste) the code above to your the functions.php file located in your theme´s folder and you upload the file to the server, The tag cloud should work.

      If you don’t see the Tag cloud, your theme might not support widgets.
      “Prerequisite: This tutorial assumes that your WordPress theme already supports widgets. To find out, check your theme´s documentation. Also it should be mentioned in your WordPress dashboard. Your theme must support widgets, for this code to work.”

      What you can do, is try my tag Cloud code on another theme and see if it works. Or if you let me know what WP theme you are actually using (give me the link to the theme and to your Website) and I will take a look to see what is the problem.