Introduction
This is a 2-part article, because there's a lot I want to talk about. Because of its relevance, I am posting it to both Web Tricks and SQL Tricks lists. I apologize ahead of time if you receive 2 of these.
This week covers Tags and Labels, Tag Clouds, and implementation when associating tags to single entities in your database, or multiple entities.
Next week I will talk about the User Interface (Associating Existing Tags and Creating New Tags), Tag Cleanup / Combining Duplicates, Tag Aliasing, Category Trees Implemented with Tags, and Multi-tag Matching.
About Tags
Tags are words you associate with web site elements (articles, products, services, blog entries, ...) that help group and organize those items.
The old method of organizing data is by hierarchical categories. Someone would create a category tree - a set of categories and sub-categories (and sometimes sub-sub-categories) and try to place every web-element into the best matching category.
The problem with this is, what happens when a web-element deserves to be in more than one category? For example, with your email, suppose you have a "friends" folder and a "jokes" folder. What happens when you receive a joke from your friend? Do you duplicate it, putting it in both folders?
As a programmer, do you duplicate elements to go into multiple categories? How do you remember all the categories it's in when you need to update it or remove it? If you have code to count such items, will it be counted twice?
Tags are the New Category
Hierarchical categories are old fashioned. A much better approach is to apply 1 or more tags to each element. Each element can have as many tags as you want. This way any element can be "categorized" into any number of categories, based on how people think about the elements, which helps people find the one they're looking for, and view elements similar to the one they found.
Many web sites today use tags, a few of which are:
Labels are Tags
Labels are another name for Tags. Google Mail (gmail.com) uses the term Label, for instance, but it's just the same idea.
Tag Clouds
You can display a tag cloud, possibly on the home page. You've seen tag clouds on web sites out there - a whole lot of words of varying font size, big and small, depending on tag's popularity (how many elements are associated with each tag). Sometimes the color or brightness of the tag indicates something else, such as how recently the last posting occurred using that tag. Dark color = very recent post, lighter color = not so recent.
You can implement the varying font size and color very easily using in-line styles. For example, suppose you want to display text size between 8 point (least popular tag) and 36 point (most popular tag).
How do you know what's most popular? You need to count tag usage:
SELECT tag.id, tag.name, COUNT(producttag.product_id) AS cnt FROM tag LEFT JOIN producttag ON producttag.tag_id=tag.id GROUP BY tag.id ORDER BY cnt DESC |
This returns the results from most-popular tag to least-popular. You can "ORDER BY tag.name" if you want the tags sorted in alphabetical order. Note that all tags are returned this way, including unused tags (cnt == 0). You could add "HAVING cnt > 0" if you don't want see those.
Once you know the count of the most-popular tag (the first row returned above), you can tell what font-size to display for each tag. Let's say the most-used tag has a cnt of "10". The formula is then:
pointsize = cnt / maxcount * (maxfontsize - minfontsize) + minfontsize |
Where "cnt" is each tag's actual usage quantity (a value between 0 and maxcount) and "maxcount" is the largest cnt possible, i.e. the usage quantity of the most popular tag.
Note: since we're dividing by maxcount, you should check at run-time to make sure that maxcount is greater than zero, otherwise you'll get a divide-by-zero error, and your web page will look screwed up.
Now, pointsize will actually be a floating-point number, so you probably want to print it as a rounded-integer; in PHP the easy way is:
printf("%.0f", $pointsize);
|
Some web sites I've seen use 1 decimal digit of accuracy, in case the web browser can handle scaling fonts by tenths of a point:
printf("%.1f", $ps);
|
Embedding this in a style is easy:
<span style="font-size:<? printf("%.0f",$ps); ?>pt">word</span>
|
So if $ps comes out to 14.938275116, the HTML you'll get is:
<span style="font-size:15pt">word</span> |
This kind of thing can help visitors find what they're looking for on your site very quickly and efficiently, making them happier with visiting your site (and more likely to bookmark it and return again later).
When they click on a word in the tag cloud, you can display all the elements (articles, or whatever) associated with that tag. Perhaps they should be displayed in order from most-recent to least-recent. This helps returning visitors see "anything new they haven't seen before", because they can simply read the articles from top down - when they encounter the ones they've seen before they can stop, knowing they've "caught up" now.
Implementation - Tagging Single Elements
Implementing tags is actually very easy, if you have a SQL database. Suppose you're designing a web log system where the owner can write articles, then apply tags to each article for visitors to click on, if they want to see other related articles.
It's a many-to-many relationship between tags and elements, so we need a "join" table to connect the two. The Entity Diagram might look like this:
Implementation - Tagging Multiple Elements
Sometimes you need to allow different kinds of elements to be tagged on your site. More than one of your database entities needs to have tags associated with them. For example, suppose you have a web site that sells products and has a company blog. Both products and blog articles can have tags.
There are various ways of doing that. You can keep all the DB tables separate, so that you have 2 completely separate tags tables, perhaps named ptag and atag.
Or, you can use a single tags table, but have different join-tables connecting the tags up to the different entity tables.
Or, you can do it all with a single tags table and join table, by adding two new fields to the join table: which type of element it is, and the id number of the element that is tagged.
Here, "tablename" is an enum with only 2 possible choices ("product" and "article"). The item_id would simply be the id number from either the product table or the article table (depending on whether tablename was set to "product" or "article").
Now, to tag a product with the tag "book", you would:
I've used this method very successfully with a web site that had 2 major data elements to it. You only want to do this if it makes sense to share the tags table across all types of elements.
Resources
What I describe above is from my own experience, but there are books out there now about developing with Tags:
Tagging: People-powered Metadata for the Social Web by Gene Smith http://safari.oreilly.com/9780321550149?a=103644
and
Building Tag Clouds in Perl and PHP a 48 page PDF by O'Reilly and Associates http://safari.oreilly.com/0596527942?a=103644
To Be Continued
Stay tuned for next week's article, where we'll discuss a whole bunch of advanced tagging features and how to implement them.
Don't miss the latest web tips and tricks!
Subscribe to our low-volume mailing list:
Privacy Policy
| Copyright © 2006 Fastech Learning LLC, all rights reserved. |
| Phone toll free 1-866-464-6688, Phoenix Metro area 480-895-6688 |
| Problem with this web site? please let us know |