Every major website seems to have a tag cloud. Users love tag clouds; they help navigate masses of content quickly and easily. When used appropriately, they help us sort filter through information stores, reduce the signal-to-noise ratio. Providing a tag cloud is also relatively painless for the server – after all, it’s just some HTML. But how do we actually build a tag cloud at application level? In this tutorial, I’ll take you through putting together a full-blown, calculated web 2.0 tag cloud in PHP.
First, let’s look at what we want to end up with. We’ll take this data:
PHP: 30 items
JavaScript: 24 items
Java: 17 items
Python: 26 items
Ruby: 17 items
And we want to end up with this tag cloud:
To do this, we need to first examine what a tag cloud is like at HTML level. Each of these tags needs to be wrapped in an element that can have a style attribute. We’ll use that to set a font size. We could use either percentages or pixels; both have advantages and disadvantages. In this tutorial, we’ll do something like this:
php
javascript
We’re using anchor tags so that we can later link them as needed.
So let’s start with our data. The above tag cloud was generated with this array:
30, 'javascript'=>24, 'java'=>17, 'python'=>26, 'ruby'=>17);
The next step in a tag cloud is calculating those font sizes. We need to define a minimum and maximum value for that font-size CSS parameter, so that we always know what sizes we’re dealing with. We then calculate the minimum and maximum values from the entire data set – array_values() will help us sort out the data – and the difference between these, the spread of the data.
Finally, we work out a "step", or an increment value for each level of items. This step will be calculated based on the difference between minimum and maximum font size, divided by the spread. This gives us a relationship between number of items and pixels for font size.
We can then work out the font size as the difference between the number of items for the current item and the lowest number of items (the minimum) in the set, multiplied by the step. This gives us the value of the font size of the current item in relation to 0. Finally, we add the minimum font size value for some width.
Let's take an example for a second. Take a new dataset, with javascript 5, php 6 and java 7. Our minimum font size is 20 and maximum size 30. Therefore $minval is 5, and $maxval is 7. Our $spread is 2, or 7-5. Our $step is ($maxsize - $minsize) / $spread, giving us 10 - 2 or 5. This means there is 4 pixels difference between each of our three values. PHP's value would be calculated like this:
This gives us 25, or 25 pixels. It's quite simple, really. Let's put all this code together, including a simple loop to run over each of the tags and spit out the HTML within a function:
$value) {
$size = round($minsize + (($value - $minval) * $step));
echo ''.$key.' ';
}
}
$tags = array('php'=>30, 'javascript'=>24, 'java'=>17, 'python'=>26, 'ruby'=>17);
tag_cloud($tags);
And we're done! A simple yet powerful PHP script to generate a web 2.0 tag cloud for your website.





9 Responses to “Building Web 2.0 Tag Clouds in PHP”
May 2, 2008
Jesse MullanWhat happens when $maxval == $minval ?
May 5, 2008
Akash Mehta@Jesse: that’s an interesting point; when $maxval == $minval, we’d have a division by zero when calculating $spread.
However, the only time this could happen is a) when you only have one tag; and b) when all your tags have equal values.
For the first scenario, I leave the validation to the developer as you would probably want to do something when you have only one tag (e.g. list items within the tag).
For the second scenario, either your site is new, you have hit quite a coincidence or you don’t need a tag cloud in the first place (because all your “tags” have equal values). Once again, I leave this up to the developer to handle outside of the function, as the function’s sole purpose is to generate a tag cloud, and I don’t wish to complicate it by adding error handling (or worse still, making it do nothing – blank outputs are the hardest to debug).
Of course, if this is an issue and you choose to handle it within the function, all it takes is an if($spread == 0) $spread = 1;.
May 5, 2008
Jesse MullanI knew the answer already — I was wondering if you had considered the edge cases.
August 19, 2008
Ridvan ROGERIt is really a simple solution, but a good soulution that is exactly; extract all words from a page as values and listing it.
May 30, 2009
AdamThank you for sharing Akash, I appreciate it.
June 6, 2009
AMANdeep MAnnIt is really a simple solution, but a good soulution that is exactly; extract all words from a page as values and listing it.
August 20, 2009
mikeok, but how do you get the links working in this tag cloud? now you have # but we needs links. Lnks would be smth like “link.php?id=tag_id” – you are only passing two arguments to function, links or tag id are missing
December 23, 2009
NZGeekmike, you would have to build an array of links, e.g.
$t = array(“php” => “http://link”, “orm” => “http://link”); etc
February 6, 2010
Joel@mike – what do you want to link to? I’d suggest putting together a “tag page” that lists entries by associated tags. So if you click on PHP it brings you to all posts with PHP tagged.
It’s easy to link, just put “tagpage.php?v=” . $key . “” and then on your tagpage.php just have one query that uses the variable $key to define the query parameters.
Hope that helps!