If you get your data model right, implementing a tagcloud turns out to be a snack. In Gravl, I’ve setup a many-to-many between BlogEntry and Tag, but I also have a link from the parent Blog directly to all available tags:

Implementing many-to-many simplifies to import process when I import my Pebble data. The import process ends up with something like this:
def tag = Tag.findByBlogAndName(newBlog, importedCat)
if (tag == null) {
tag = new Tag(name: importedCat)
log.debug "Creating new tag for ${importedCat}"
// Grails handles the bidirectional link for us
newBlog.addToTags(tag).save()
} else {
log.debug "Found existing tag for ${importedCat}"
}
newEntry.addToTags(tag).save()
Once you’ve got an easy way to access all tags for a blog, and a count of how many times they occur, you’re all set to following a simple tag cloud algorithm. Sounds like a perfect case for a TagCloudTagLib? Needs some error handling, but here’s a first cut (apologies for the formatting):
class TagCloudTagLib {
// Simple Algo from http://www.petefreitag.com/item/396.cfm
def tagCloud = {attrs, body ->
def blogId = attrs.blogId
Blog blog = Blog.findByBlogid(blogId)
log.debug "Building tagcloud for: $blog.title"
// step 1: determine tags and their frequency
def tagToFreq = new TreeMap()
blog.tags.each {tag ->
def tagCount = tag.entries.size()
tagToFreq[tag.name] = tagCount
log.debug "Setting size of ${tag.name} to $tagCount"
}
def allFreq = tagToFreq.collect {tag, freq -> return freq}.sort()
def minFreq = allFreq[0] // first entry
def maxFreq = allFreq[-1] // last entry
log.debug "Max is $maxFreq and min is $minFreq"
// step 3: find the spread, use 5 font sizes
def distrib = maxFreq - minFreq
def catSize = (distrib / 5).intValue() + 1 // add 1 to simulate ceil()
// step 4: output your tags
tagToFreq.each {tag, freq ->
out << "<a href='/$blogId/tags/$tag' class='tagCloudSize" + (freq / catSize).intValue() + "'>"
out << tag
out << "</a> "
log.debug "Tag class of $tag with size $freq is " + (freq / catSize).intValue()
}
}
}
Which make using tagclouds in a gsp as easy as:
<g:tagCloud blogId="glen"/>
Or something more dynamic..
Of course, you’ll want to style those bad boys once you put them in a GSP. But the CSS is pretty straightforward:
.tagCloudSize0 { font-size: xx-small; }
.tagCloudSize1 { font-size: small; }
.tagCloudSize2 { font-size: medium; }
.tagCloudSize3 { font-size: large; }
.tagCloudSize4 { font-size: xx-large; }
And the result? Well… I really need to add some more categories for my blogging… Or get a more balanced life:

If you’d like to have a more detailed browse of the source, I’m hosting at google code for now. Check out the source page. It’s all Apache2.
Ok… Tagclouds done… Now on to some calendaring…