Subscribe to the MPC blog rss feed feed-icon-14x14
 

Creating a tag cloud



Posted on 07:37PM on 09/08/2008
Tags: django, python

I'm working with Python and Django at the moment (essentially just replicating this site) and I wanted to produce the same tag cloud that can be seen to the right of this blog. Basically, I want it to display all my tags, randomly, with a count of each tag and with the font size of the link controlled by the count. In other words, the more entries for a particular tag, the bigger that tag's font. Why? I don't know - I guess I just like the concept.

So the first thing to do is make sure that we can get a randomized list of all tags.

class Post(models.Model):
    #other code
    @classmethod
    def all_tags(self):
        container = {}
        for post in Post.objects.all():
            tag_array = post.tags.split(",")
            for tag in tag_array:
                tag = tag.strip()
                if container.has_key(tag):
                    container[tag] += 1
                else:
                    container[tag] = 1
         result = []
         for tag, count in container.iteritems():
             result.append(Tag(tag, count))
         random.shuffle(result)
         return result

So, that's great. Now I have a randomized list of Tag objects. Now, how do I display them?

Obviously, I need to iterate over the tags in my template and output them as links. That's pretty straight forward: create a template called tags.html. But how do I control the size of the link?

The answer is a custom filter. Here's the code:

from django import template
from django.utils.safestring import mark_safe
register = template.Library()

@register.filter(name='randomize_tag_size')
def randomize_tag_size(tag):
    map = {1:  "8px", 2: "12px", 3: "14px", 4:  "18px", 5: "20px", 6: "24px"}
    maximum = max(map.keys())
    minimum = min(map.keys())
    font = ""
    if tag.count >= maximum:
        font = map[maximum]
    elif tag.count <= minimum:
        font = map[minimum]
    else:
        font = map[tag.count]
    return mark_safe("style='font-size: %s'" % font)

Then, in your tags.html template, simply call {{ tag|randomize_tag_size }} within your link tag and you'll get a style

0 Comments (Show) (Comments are closed for this post)

 
Please note that I am currently unavailable for any large, long term work.