///Building Web 2.0 Tag Clouds in PHP

Building Web 2.0 Tag Clouds in PHP

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:

php javascript java python ruby

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.

2008-05-02T06:00:00+00:00 May 2nd, 2008|PHP|9 Comments

About the Author:

9 Comments

  1. Jesse Mullan May 2, 2008 at 2:19 PM

    What happens when $maxval == $minval ?

  2. Akash Mehta May 5, 2008 at 6:51 AM

    @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;.

  3. Jesse Mullan May 5, 2008 at 7:36 AM

    I knew the answer already — I was wondering if you had considered the edge cases.

  4. Ridvan ROGER August 19, 2008 at 9:04 AM

    It is really a simple solution, but a good soulution that is exactly; extract all words from a page as values and listing it.

  5. Adam May 30, 2009 at 5:43 AM

    Thank you for sharing Akash, I appreciate it.

  6. AMANdeep MAnn June 6, 2009 at 6:08 AM

    It is really a simple solution, but a good soulution that is exactly; extract all words from a page as values and listing it.

  7. mike August 20, 2009 at 2:07 AM

    ok, 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

  8. NZGeek December 23, 2009 at 6:29 AM

    mike, you would have to build an array of links, e.g.
    $t = array(“php” => “http://link”, “orm” => “http://link”); etc

  9. Joel February 6, 2010 at 9:45 PM

    @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!

Leave A Comment