Clean WordPress tag cloud

The default WordPress tag cloud includes nasty stuff like inline styling. I needed to be able to style the tags with a single class that included the tag weight in its name. It also needed the tags to be displayed in a list. The result turned the separate tag markup from

<a href="http://randomsite.com/tag/lolcats/" class="tag-link-5" title="3 tag" style="font-size: 32pt">Lolcats</a>

into

<li class="tag-10">
	<a href="http://randomsite.com/tag/lolcats/">Lolcats</a>
</li>

First we create a simple value object representing a tag.

class Custom_Tag
{
	var $name, $link, $class;
	
	public function Custom_Tag($name, $link, $class)
	{
		$this->name = $name;
		$this->link = $link;
		$this->class = $class;
	}
}

Then we go through all the tags and assign each a class depending on its weight. Those occurring the least will get the class tag-1 and those occurring most frequent will get the class tag-10. The function will return an array of Custom_Tag objects.

function custom_generate_tag_cloud($tags)
{
	if($tags) {
		$smallest_class = 1;
		$largets_class = 10;
		
		$counts = array();
		foreach ($tags as $key => $tag) {
			$counts[$key] = $tag->count;
		}
		
		$min_count = min($counts);
		$spread = max($counts) - $min_count;
		if ( $spread <= 0 )
			$spread = 1;
		
		$class_spread = $largets_class - $smallest_class;
	        if ( $class_spread < 0 )
	                $class_spread = 1;
	        $class_step = $class_spread / $spread;
		
		$cloud_tags = array();
		foreach ($tags as $key => $tag) {
			$count = $counts[$key];
			$class = 'tag-' . round($smallest_class + ( ( $count - $min_count ) * $class_step ));
			$cloud_tags[] = new Custom_Tag($tag->name, $tag->link, $class);
		}
	}
	
	return $cloud_tags;
}

Finally we collect the tag objects created in the function above and output some html. We also add a filter hook for “wp_generate_tag_cloud”.

function custom_tag_cloud($return, $tags, $args)
{
	$tag_array = custom_generate_tag_cloud($tags);
	$cloud_tags = array();
	
	$return = "<ul>\n";
	foreach ($tag_array as $tag) {
		$cloud_tags[] = '<li class="' . $tag->class . '"><a href="' . $tag->link . '">' . $tag->name . "</a></li>\n";
	}
	$return .= join('', $cloud_tags);
	$return .= "</ul>\n";
	
	return $return;
}

add_filter('wp_generate_tag_cloud', 'custom_tag_cloud', 10, 3);