None

Gravatars in Django

December 22, 2009

Gravatars are small avatars, centrally hosted, keyed by email address. This means that you can use them on multiple sites. It's also possible to generate them on the fly, with a choice of the style - there are two flavours of monster, or geometric shapes. This technology is used by stackoverflow.com, and I've just added it to Brass Band Results.

Template Tag

To do this, I used a project called django-gravatar, which simply adds some django template tags. Here's the template tag source I ended up using (code from django-gravatar, with just a change to the constant for default images):

from django import template
from django.utils.html import escape
from django.contrib.auth.models import User
from django.conf import settings
from django.utils.hashcompat import md5_constructor

import urllib

GRAVATAR_URL_PREFIX = getattr(settings, "GRAVATAR_URL_PREFIX", "http://www.gravatar.com/")
GRAVATAR_DEFAULT_IMAGE = getattr(settings, "GRAVATAR_DEFAULT_IMAGE", "identicon")

register = template.Library()

def get_user(user):
    if not isinstance(user, User):
        try:
            user = User.objects.get(username=user)
        except User.DoesNotExist:
            # TODO: make better? smarter? strong? maybe give it wheaties?
            raise Exception, "Bad user for gravatar."
    return user

def gravatar_for_email(email, size=80):
    url = "%savatar/%s/?" % (GRAVATAR_URL_PREFIX, md5_constructor(email).hexdigest())
    url += urllib.urlencode({"s": str(size), "default": GRAVATAR_DEFAULT_IMAGE})
    return escape(url)

def gravatar_for_user(user, size=80):
    user = get_user(user)
    return gravatar_for_email(user.email, size)

def gravatar_img_for_email(email, size=80):
    url = gravatar_for_email(email, size)
    return """<img src="%s" height="%s" width="%s" border="0"/>""" % (escape(url), size, size)

def gravatar_img_for_user(user, size=80):
    user = get_user(user)
    url = gravatar_for_user(user)
    return """<img src="%s" alt="Avatar for %s" height="%s" width="%s" border="0"/>""" % (escape(url), user.username, size, size)

def gravatar(user, size=80):
    # backward compatibility
    return gravatar_img_for_user(user, size)

register.simple_tag(gravatar)
register.simple_tag(gravatar_for_user)
register.simple_tag(gravatar_for_email)
register.simple_tag(gravatar_img_for_user)
register.simple_tag(gravatar_img_for_email)

Note that the GRAVATAR_DEFAULT_IMAGE constant defaults to identicon. This gives geometric shapes; the other options both give monsters and are wavatar and monsterid. For more details on what these options produce see the gravatar blog.

Template

In the template, simply import the tags, then use the gravatar tag passing in a user and a size.

{% load gravatar %}

{% gravatar ContestEvent.owner 40 %}

Use without Django User objects

See this blog for details of using gravatars without requiring a django user object.