Posts Tagged ‘xhtml’

PHP and MySQL Tag Cloud

This tutorial shows you how to write a simple Tag Cloud using PHP and MySQL and presenting using standard XHTML and CSS.

The basis of using this is that you have a database for your journal entries… most blogging engines follow this approach.

To start with we need to create a couple of new database tables. One will simply hold the list of available tags and the other will hold records which will match journal entries to the tags that are listed against them. For this tutorial I have a table named “tags” which has 2 columns, 1 named id which is an auto_increment column and the other is a string field which holds the tag text. The other table is named “article_tags” which also has two columns. The first field holds the id from the “tags” table and the second field holds the id value of the journal entry.

To output the tag cloud we essentially count up the number of entries in the article_tag table for each tag. We also have 5 “levels” of tag which are are used to assign a class to the outputted XHTML which will be used to assign a different display property to for each level of popularity of the tags. I have actually been a bit poor in my implementation of the class names for each level of popularity and have given then names such as “largest”. I really should have used names like “tag_level_5″ which would remove the presentation information from the XHTML whilst keeping it semantically correct.

The PHP used has been put into a function which outputs all the tags in an unordered list. This means that if the site is viewed with CSS disabled or via another presentation method for example a screen reader that the page still makes sense. This approach is also useful in terms of how the site is seen by search engines.

// ################################
// TAG CLOUD
// ################################
function tag_cloud(){
  echo "<div id='tag_cloud_div'>
    <h2>tag cloud</h2>
    <ul>\n";
  $tag_query = "SELECT count(article_tags.tag_id),
  tags.tag from article_tags
  left join tags on article_tags.tag_id = tags.id
  group by article_tags.tag_id order by tags.tag";
  $tag_result = mysql_query($tag_query);
  $lowest = 25;
  $highest = 0;
  while ($tag_data = mysql_fetch_row($tag_result)) {
    $tags[$tag_data[1]] = $tag_data[0];
    if ($tag_data[0] < $lowest) {
      $lowest = $tag_data[0];
      }
    if ($tag_data[0] > $highest) {
      $highest = $tag_data[0];
      }
    }
  $step = (($highest - $lowest) / 5);
  $smallest_tag = $lowest;
  $small_tag = $smallest_tag + $step;
  $medium_tag = $small_tag + $step;
  $large_tag = $medium_tag + $step;
  $largest_tag = $medium_tag + $step;
  foreach ($tags as $key => $value){
    if ($value >= $largest_tag) $tag_class = 'largest_tag';
    else if ($value >= $large_tag) $tag_class = 'large_tag';
    else if ($value >= $medium_tag) $tag_class = 'medium_tag';
    else if ($value >= $small_tag) $tag_class = 'small_tag';
    else $tag_class = 'smallest_tag';
    echo "<li class='$tag_class'><a href='/articles/tag/$key'>$key</a></li>\n";
    }
  echo "  </ul>
    </div>\n";
  ?>
  </div>
  <?
}

CSS is then used to style the output so it’s displayed as stream of text where the font size for each tag is dependant on the class which was assigned above (which relates to how popular the tag is).

#tag_cloud_div {
  float:right;
  width:275px;
  padding: 10px;
  border: 1px solid #3F3C20;
  background-color: #DAD306;
  }

#tag_cloud_div li{
  display: inline;
}

#link_list_div {
  float:right;
  width:275px;
  padding: 10px;
  border: 1px solid #3F3C20;
  background-color: #12C6CC;
  margin-bottom: 10px;
  }

#tag_cloud_div h2, #link_list_div h2 {
  margin-bottom:0.3em;
  color: #3F3C20;
  }

#link_list_div li {
  margin-bottom:0.2em;
  }

.smallest_tag{
  font-size: 0.8em;
  line-height: 0em;
  }

.small_tag{
  font-size: 1.0em;
  line-height: 0.4em;
  }

.medium_tag{
  font-size: 1.3em;
  line-height: 0.9em;
  }

.large_tag{
  font-size: 1.8em;
  line-height: 1em;
  }

.largest_tag{
  font-size: 2.2em;
  line-height: 1.3em;
  }

This is by no means the best method of creating a tag cloud but it demonstrates how simple it can be. To enhance this (as I said earlier) I’d prefer to rename the classes used and would also probably look to make the popularity of the tag dependant on other aspects such as time of publication of the journal entries.