Customize Tags Cloud in WordPress

Tags cloud is a visualization of the tags used in a site. Using tags cloud, users can easily see the most used tags from the visualization used in the cloud.

WordPress has built-in widget that can be used to display tags cloud. The visualization of the tags cloud in this widget is very simple. By default, the tags are displayed alphabetically with different font size depends on number of articles use a particular tag. There are some customizations that you can do by using filter, but not many. For example, you cannot give different color for each tag in the cloud.

This article explains how to customize the tags cloud in WordPress, specifically to make it easier to give different color for tags in the cloud.

You can find the code for the tags cloud widget in WordPress inside file wp-includes/default-widgets.php. The class name for this widget is WP_Widget_Tag_Cloud. Examining the code, the first customization that you can do is by using filter widget_tag_cloud_args, which is called when the widget creating the cloud by calling wp_tag_cloud function. The widget_tag_cloud_args filter allows you to provide additional arguments for function wp_tag_cloud.

Function wp_tag_cloud itself is inside wp-includes/category-template.php file. Looking at the code, you can customize the font size, how many tags you want to display, the ordering of the tags, etc.

For example, if you want to customize the ordering and font size, you can create a filter as follow:

function kana_wp_tag_cloud_ordering_filter($args)
{
	$args['order'] = 'DESC';
	$args['smallest'] = 10;
	$args['largest'] = 30;
}

add_filter('widget_tag_cloud_args',
	'kana_wp_tag_cloud_ordering_filter');

Put the above code in your functions.php file inside your theme folder.

In the above example, we set the ordering of the tags as descending and the smallest font size is 10pt, and the largest font size is 30pt.

Function wp_tag_cloud reads all tags from database ordered initially from the most used tag. Then it calls function wp_generate_tag_cloud and passes the previously read tags and arguments that we supply from the previous filter.

Inside function wp_generate_tag_cloud (in the same file as function wp_tag_cloud), we have a chance to filter the ordering of the tags beside the one that you specify by using the arguments in previous filter. If you filter the ordering here, the one specified from the previous filter will be ignored.

If you want to create your own ordering, you can use this filter to do it:

function kana_tag_cloud_sort_filter($tags, $args)
{
	// your ordering function here
}

add_filter('tag_cloud_sort',
	'kana_tag_cloud_sort_filter', 10, 2);

The function wp_generate_tag_cloud then creates the tags cloud. It returns the tags base on the arguments specified, that is either as an array, a list, or by default a flat text.

When creating tags cloud, WordPress initializes the link for each tag. The code to create the link is (rewritten for space constraint):

$a[] = "<a href='$tag_link' class='tag-link-$tag_id' "
	. "title='"
	. esc_attr($topic_count_text_callback($real_count))
	. "' style='font-size: "
	. ($smallest + (($count - $min_count) * $font_step))
	. "$unit;'>$tag_name</a>";

You can see from this function that the link to the tag does not have any class that can be used to customize the tag base on the number of the articles use that tag. We will look at how we can solve this problem later on.

Now we have the tags cloud for the widget. However, if you look at the code generated by this widget, there is now way to differentiate it from other widgets. Here is an example of the code generated by this widget:

<div class="side_bar_sec">
	<h2>Tag Clouds</h2>
	<div>
		<a href='http://localhost/tag/google/'
			class='tag-link-9' title='3 topics'
			style='font-size: 22pt;'>Google</a>
		<a href='http://localhost/tag/groupon/'
			class='tag-link-8' title='1 topic'
			style='font-size: 8pt;'>Groupon</a>
		<a href='http://localhost/tag/news/'
			class='tag-link-5' title='1 topic'
			style='font-size: 8pt;'>News</a>
		<a href='http://localhost/tag/temporary/'
			class='tag-link-12' title='1 topic'
			style='font-size: 8pt;'>Temporary</a>
	</div>
</div>

So, if we want to give different color for the tag which is used on 2 articles, we will not be able to do it.

To solve this problem, we can hack into function wp_generate_tag_cloud which creates the link, but doing so will be difficult to maintain your code because when new version of WordPress comes out, you need to remember to edit that function again.

The better solution is by using JavaScript to add new class to the link. We will use jQuery to do it because it is used by default in WordPress. The idea is to find all the links in the tags cloud, and add different new class base on the number of the title on the link. For example, for the link with title=’1 topic’ we will add topic_count_1 class. For the link with title=’2 topics’ we will add topic_count_2 class, etc. Having the class name, we can easily customize the visualization by using CSS.

In other to easily to do that, we need to make one change on the code produced by the widget. As you can see from the code above, there is no efficient way to find all the links in the tags cloud by using jQuery. We can use side_bar_sec class but doing so we will search all links on all widgets. What we want to do is to have a div with class just before the links so we can search for the link efficiently.

To add the div with a class, we can look back at function wp_tag_cloud and wp_generate_tag_cloud. Near the completion of these functions, we can see that we can apply filter to the tags links that already created. In this case we will use the filter inside wp_tag_cloud function. With this filter we will add a new div with a class. The code is:

function kana_wp_tag_cloud_filter($return, $args)
{
	return '<div class="tags_cloud">'.$return.'</div>';
}

add_filter('wp_tag_cloud',
	'kana_wp_tag_cloud_filter', 10, 2);

With this filter, now output is:

<div class="side_bar_sec">
	<h2>Tag Clouds</h2>
	<div>
		<div class="tags_cloud">
			<a href='http://localhost/tag/google/'
				class='tag-link-9' title='3 topics'
				style='font-size: 22pt;'>Google</a>
			<a href='http://localhost/tag/groupon/'
				class='tag-link-8' title='1 topic'
				style='font-size: 8pt;'>Groupon</a>
			<a href='http://localhost/tag/news/'
				class='tag-link-5' title='1 topic'
				style='font-size: 8pt;'>News</a>
			<a href='http://localhost/tag/temporary/'
				class='tag-link-12' title='1 topic'
				style='font-size: 8pt;'>Temporary</a>
		</div>
	</div>
</div>

Now we have a class that we can use to search for all the links in tags cloud. The JavaScript code to add new class to the links is:

jQuery().ready(function() {
	jQuery(".tags_cloud a").each(function() {
		checkTagsCloud(this);
		return true;
	});
});

function checkTagsCloud(thisObj) {
	var title = jQuery(thisObj).attr('title');
	if (title) {
		var titles = title.split(' ');
		if (titles[0]) {
			var num = parseInt(titles[0]);
			if (num == 2)
				jQuery(thisObj).addClass('topic_count_2');
			if (num == 3)
				jQuery(thisObj).addClass('topic_count_3');
			if (num == 4)
				jQuery(thisObj).addClass('topic_count_4');
			if (num == 5)
				jQuery(thisObj).addClass('topic_count_5');
			if ((num > 5) && (num <= 10))
				jQuery(thisObj).addClass('topic_count_10');
			if ((num > 10) && (num <= 15))
				jQuery(thisObj).addClass('topic_count_15');
			if ((num > 15) && (num <= 20))
				jQuery(thisObj).addClass('topic_count_20');
			if (num > 20)
				jQuery(thisObj).addClass('topic_count_30');
		}
	}
	return true;
}

First, we look at all the links inside tag_cloud class. For each link, we pass it to the function checkTagsCloud. Inside this function, the title of the link will be read, and then we get the number by using the split function. Base on the number that we have on the title, we add a new class to that link.

Note: You need to be careful with the checkTagsCloud function. It assumes that you are using default topic_count_text_callback function. If you are using customized function, you need to adjust the checkTagsCloud function accordingly.

The default topic_count_text_callback function in WordPress is:

function default_topic_count_text( $count ) {
	return sprintf(_n('%s topic','%s topics',$count),
		number_format_i18n($count));
}

With this JavaScript, the generated code is:

<div class="side_bar_sec">
  <h2>Tag Clouds</h2>
	<div>
		<div class="tags_cloud">
			<a href='http://localhost/tag/google/'
				class='tag-link-9 topic_count_3'
				title='3 topics'
				style='font-size: 22pt;'>Google</a>
			<a href='http://localhost/tag/groupon/'
				class='tag-link-8' title='1 topic'
				style='font-size: 8pt;'>Groupon</a>
			<a href='http://localhost/tag/news/'
				class='tag-link-5' title='1 topic'
				style='font-size: 8pt;'>News</a>
			<a href='http://localhost/tag/temporary/'
				class='tag-link-12' title='1 topic'
				style='font-size: 8pt;'>Temporary</a>
		</div>
	</div>
</div>

Now we can easily give different color for the tags link. You can see the example of this method in the Hot Topics box on the side of this site.

Post a Comment

Leave your comment below
The comment is moderated. Only comments related to the post will be accepted.
Your name
Email address
Your comment

Read Comments 5 Comment feed

  • Is it possible or is there already a solution to have a cloud search a site for content.
    IE a “domain.com/cloud” page that dynamicly updates based on posts on page “domain.com”

  • Very helpful post to help me write a filter to replace the default title tags

  • THANK YOU! So many wrong ways to do this on the web and you show me the right way to pass new arguments via the filter.

    You do have an error in the code you forget to return $args at the end of the function, but I figured that part out.

  • Thank you!

    That first snippet of code was exactly what I was looking for.

    I do have to reiterate what James said — it’s missing the “return $args;” line — but once that’s added, works well.

    • it’s possible to change the href of tag? and how?

Printed:
Beta
You can get this information from:
http://www.kanasolution.com/2011/01/customize-tags-cloud-in-wordpress/
Close this window
Email This Information
To send the message, please fill the form below
Email To
Subject
Message
Your Email
Validation

Please enter the text on the following image in the verification box below. Click here if you cannot read the text. All alphabets are in upper case.

Verification image