Basic Tag Cloud

This post assumes basic understanding of PHP, HTML, and CSS.

Creating my blog by hand gave me the opportunity to work with many features that come standard with online blogging software. I developed tag clouds, post filtering, and the search functions based on the visual functionality that other blogs appeared to have. With this post, I'm going to explain how to make a tag cloud using PHP and CSS that can be implemented on any type of article- or post-based environment.

Most blogs that use tags allow multiple tags per post and tags being placed on multiple posts. The tag not only helps explain what the post is about, but also gives basic navigation based on tag for users interested in a specific blog category. A tag cloud provides the navigation with an additional feature: tags that are used more often in the blog are increased in font size, giving them more weight compared to less-used tags.

The first thing that you'll need is a PHP array of all your blog tags. The creation of this array is wholly dependent on your blog setup - I have all my tags in a separate table, so I just did a SQL select command and pulled out an array. If your blog is basic, you may have a manual array or have to loop through a larger table setup. The important thing is to have a non-unique array of your blog tags. If a tag is used twice, it should be in your array twice. Once you have the array, a simple array_count will simplify the array down and give you the number of times each tag appears in your array - exactly what we'll need.

  1. /*

  2. Array before the command

  3. $tags = array(

  4. 'css',

  5. 'huron mountains',

  6. 'huron mountains',

  7. 'php',

  8. 'php',

  9. 'logan'

  10. );

  11. */

  12. $tags = array_count_values($tags);

  13. /*

  14. Array after the command

  15. $tags = array(

  16. 'css' => 1,

  17. 'huron mountains' => 2,

  18. 'logan' => 1,

  19. 'php' => 2

  20. );

  21. */

There are several ways to actually display the tags and apply the needed size changes. I prefer a strict xHTML-no inline CSS environment, so I'll apply classes to each tag based on count value and worry about the sizes in my stylesheet. Now I need to loop through my counted array, display the tags, giving the tags with the highest value the largest size and smallest value the smallest size, mapping everything else in between.

  1. /*

  2. Loop through tags array and look for the min/max

  3. */

  4. foreach($tags as $row)

  5. {

  6. if(($row['count(tag)']<$min)||(!$min))

  7. $min = $row['count(tag)'];

  8. if(($row['count(tag)']>$max)||(!$max))

  9. $max = $row['count(tag)'];

  10. }

  11. /*

  12. Loop through tags array and display in an unordered list, applying class

  13. */

  14. ?>

    • <?

    • foreach($tags as $tag => $count)

    • {

    • ?>

    • <li><a class="size<?=floor(($count-1)*(9/($max-$min)))?>" href="<?=$url?>tag_<?=r($tag,url)?>/"><?=str_replace(' ',' ',$tag)?></a></li>

    • <?

    • }

    • ?>

    • </ul>

There is some difficult math in there, but the math inside of the floor function will pull an integer between 0-9 (inclusive) based on the count of the tag. The math will map a large or small range of count to a smaller, easy to handle range. Even if I use a tag forty or fifty times, it will never have a class larger the size9. Note - the r function is a simple renamer that prepares the tag for the URL (replace blank spots and whatnot) - don't worry about it.

The last step is the css. I included a bit of my styles that control the overall tag_cloud appearance as well.

  1. .tag_cloud ul li {display:inline;line-height:110%;}

  2. .tag_cloud ul li a {padding:5px 2px;}

  3. .tag_cloud .size0 {font-size:9px;}

  4. .tag_cloud .size1 {font-size:10px;}

  5. .tag_cloud .size2 {font-size:11px;}

  6. .tag_cloud .size3 {font-size:12px;}

  7. .tag_cloud .size4 {font-size:13px;}

  8. .tag_cloud .size5 {font-size:14px;}

  9. .tag_cloud .size6 {font-size:15px;}

  10. .tag_cloud .size7 {font-size:16px;}

  11. .tag_cloud .size8 {font-size:17px;}

  12. .tag_cloud .size9 {font-size:18px;}

The CSS is the only repetitive piece - you could simplify it with a bit of PHP, but I usually avoid having script in my stylesheets for performance and aesthetic reasons.

These bits of code will give you a basic tag cloud, similar to the one I use in this blog, without inline styles or a third party plug-in. Hope you enjoy it!