http://www.developer.com/

Back to article

Create Tag Clouds with the Zend Framework's Zend_Tag_Cloud Component


July 15, 2010

A great way to empower online customers while conveniently reducing the burden of organizing your company's website is by providing a mechanism for tagging online content. Tagging allows customers to choose terms that best describe a particular product, blog post, or service, and then you can organize those tags in such a way that other customers can use them to navigate the website. Such navigational features are known as tag clouds, and you'll find them popping up everywhere, including sites such as Amazon.com (see Figure 1).

Amazon.com's Great Product Tagging Feature
Figure 1. Amazon.com's Great Product Tagging Feature

In this tutorial I'll show you how to create your own tag clouds using the Zend Framework's Zend_Tag_Cloud component, which you can use to tag up every conceivable part of your website, from products to blog posts. This component is a native part of the Zend Framework, meaning if you already use the Zend Framework to power your website, integrating tag cloud capabilities will be trivially easy.

Creating a Tag Cloud

You can generate a tag cloud by passing a multidimensional array to the Zend_Tag_Cloud constructor. Each associative array found in the multidimensional array will represent one tag, consisting of a tag title, URL (which the tag should point towards when the URL is linked) , and a weight, which indicates the frequency of the tag's use as related to other tags in the collection. For instance, the following example defines four tags (History, Economics, Science Fiction and Science) that might be used to categorize a book store.

$cloud = new Zend_Tag_Cloud(array(  'tags' => array(      array('title' => 'History', 'weight' => 16,            'params' => array('url' => '/tag/history')),      array('title' => 'Economics', 'weight' => 25,            'params' => array('url' => '/tag/economics')),      array('title' => 'Science Fiction', 'weight' => 12,            'params' => array('url' => '/tag/science-fiction')),      array('title' => 'Science', 'weight' => 7,            'params' => array('url' => '/tag/science')),  );));

You can then render the tag to the screen simply by echoing the $cloud variable. The results are presented in Figure 2.

Rendering the Book Store Cloud
Figure 2. Rendering the Book Store Cloud

Notice how the font sizes differ according to the weighting assigned to each tag. This is what makes it possible for users to easily determine what types of content are more prevalent on your site. But this automated feature is probably of secondary concern to you at the moment, because the example presented in Figure 2 doesn't actually look like a cloud at all! This is because the Zend Framework makes no assumptions in terms of what you'd like your cloud to ultimately look like when rendered to the browser. Instead, it provides a starting point from which you can tweak the cloud layout. Read on to learn how to do this.

Decorating Your Tag Cloud

Relying on frameworks to generate the code used for features such as HTML forms, tag clouds and paginated database results often means sacrificing some control over the look and feel. Not so with the Zend Framework, thanks to the diligent use of decorators throughout the components. Developers can use these decorators to customize how the component's generated code is rendered to the browser.

Specifically, you can use these decorators in conjunction with CSS to both stylize how the tag cloud is presented in its entirety, such as adding a background color to the cloud, and stylize each tag using a specific font. Here's the revised example:

$cloud = new Zend_Tag_Cloud(array(    'tags' => array(        array('title' => 'History', 'weight' => 16,              'params' => array('url' => '/tag/history')),        array('title' => 'Economics', 'weight' => 25,              'params' => array('url' => '/tag/economics')),        array('title' => 'Science Fiction', 'weight' => 12,              'params' => array('url' => '/tag/science-fiction')),        array('title' => 'Science', 'weight' => 7,              'params' => array('url' => '/tag/science')),    ),    'cloudDecorator' => array(      'decorator' => 'HtmlCloud',      'options' => array (        'htmlTags' => array (          'div' => array ('id' => 'tags')        ),        'separator' => ' '      )    ),    'tagDecorator' => array (      'decorator' => 'HtmlTag',      'options' => array (        'htmlTags' => array ('span')      )    )));

Combine this revised example with a simple bit of CSS to restrict the cloud width:

#tags {  width: 200px;}

If you render the revised cloud to the browser, you'll see we're moving much closer to the desired goal, as demonstrated in Figure 3.

Rendering the Book Store Cloud
Figure 3. Stylizing the Cloud with Decorators and CSS

Even this is still a bit bland for my tastes. What if we took it a step further, stylizing the tags according to their weight? Revise the tagDecorator so that it looks like this:

'tagDecorator' => array (  'decorator' => 'HtmlTag',  'options' => array (    'htmlTags' => array ('span'),    'classList' => array('tag1', 'tag2', 'tag3', 'tag4')  ))

Now add the following classes to your CSS document:

.tag1 {  font-size: 12px;  color: blue;}.tag2 {  font-size: 14px;  color: purple;}.tag3 {  font-size: 16px;  font-weight: bold;  color: orange;}.tag4 {  font-size: 20px;  font-weight: bold;  color: red;}

With the revised scripts in place, you should see the tag cloud presented in Figure 4.

Rendering the Book Store Cloud
Figure 4. Customizing Your Cloud Tags

Associating Tags with Content

Of course, tags serve no purpose without the ability to associate them with content such as products or blog entries. Currently, neither the Zend_Tag_Cloud nor the sibling Zend_Tag component offers a native way to save or retrieve tags. They don't provide a way for directly associating them with a particular model either, meaning you'll need to devise your own solution to this task. However, because the only real requirement in terms of rendering the cloud is that you pass the expected array to the Zend_Cloud constructor, my preferred solution at this point involves creating a tag model/table and a corresponding model/table for mapping the tags to the desired model. Using Zend_Db's model relationship features, the rest is pretty trivial. For instance, if we wanted to tag blog entries, the tags table might look like this:

mysql> describe tag;+-----------+------------------+------+-----+---------+----------------+| Field     | Type             | Null | Key | Default | Extra          |+-----------+------------------+------+-----+---------+----------------+| id        | int(10) unsigned | NO   | PRI | NULL    | auto_increment | | title     | varchar(200)     | NO   |     | NULL    |                | | permalink | varchar(200)     | NO   |     | NULL    |                | +-----------+------------------+------+-----+---------+----------------+

A mapping table used to associate blog entries with tags would look like this:

mysql> describe blogs_to_tags;+---------+------------------+------+-----+---------+----------------+| Field   | Type             | Null | Key | Default | Extra          |+---------+------------------+------+-----+---------+----------------+| id      | int(10) unsigned | NO   | PRI | NULL    | auto_increment | | blog_id | int(10) unsigned | NO   |     | NULL    |                | | tag_id  | int(10) unsigned | NO   |     | NULL    |                | +---------+------------------+------+-----+---------+----------------+

From here, retrieving an all-encompassing tag cloud complete with weightings based on frequency, or a blog entry's tags, or a list of blog entries according to a tag is as easy as writing a few SQL queries!

Conclusion

The Web's remarkable ability to self-organize in spite of lacking a centralized controlling body has taught us volumes about sociology, economics and the marketplace. It has also taught businesses that maintaining white-knuckle control over their products and content isn't always the easiest path to profitability -- let alone the way to win over customers.

This transformation has taken place gradually, beginning with something as simple as allowing customers to post product reviews, both good and bad. After confirming that an immediate cessation of business operations wasn't inevitable after all, control was loosened in other areas, including offering support forums and maintaining open product wikis. Perhaps the customer is king after all!

By implementing tag clouds, you provide customers with an efficient way to organize website content according to terms that make the most sense to the marketplace, while simultaneously removing the burden of organization from the website owner. Are you using tag clouds in interesting and compelling ways to organize your material? Tell us about it in the comments!

About the Author

Jason Gilmore is founder of WJGilmore.com. He also is the authorof several popular books, including "Easy PHP Websites with the Zend Framework","Easy PayPal with PHP", and"Beginning PHP and MySQL, Third Edition".

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date