The Bitter Pill

50,000 watts of power … Got my radio on

Stupidly simple microformat syncing with Django’s generic views.

Creating a one-click sync between your microformat data and a visitor’s address book or calendar couldn’t be simpler with Django. In fact, the built-in generic views give you everything you need.

If you use Django, it seems inevitable that the database will quickly have a lot of data that just lends itself to microformats, particularly calendar events and contact information. So, I’ve been playing around with microformats quite a bit lately and spitting out hcalendar and hcard microformats all over the place.

But there’s been this persistent sticking point: getting the hcard or hcalendar data into the user’s address book or calendar. They don’t care about my nifty semantic markup. I’ve got to provide a real benefit to them. Frankly, expecting the visitor to have a Greasemonkey script or bookmarklet installed is expecting way too much. This should be as simple as a button or link that says “Add this to your address book.”

Via Jeff Croft I saw Derek Willis’ solution for doing this with vobject. Looks like a great solution for icalendar links, but vobject struggles a bit with vcard, and I couldn’t get it to install on my shared server, so I kept looking.

From Derek’s article, I went back to Boomby.com and saw how to do it with a template instead of vobject… but then it hit me — generic views will work for this.

So, here’s how to create an “Add this” link in just a few lines of code:

in urls.py, add something like:
(r'^card/(?P<slug>[-\w]+)/$', 'django.views.generic.list_detail.object_detail', dict(queryset=Foo.objects.all(), slug_field='slug', template_name="microformats/vcard.html",mimetype="text/x-vcard") ),

Where, obviously, Foo is your model. And note it has to have a slug field.
Then, you just need a simple template:

BEGIN:VCARD
VERSION:3.0
ORG: {{object.name}}
FN:{{object.contact_name}}
STREET-ADDRESS:{{object.contact_address}}
LOCALITY:{{object.contact_city}}
REGION:{{object.contact_state}}
POSTAL-CODE:{{object.contact_zip}}
TEL:{{object.contact_phone}}
END:VCARD

As Derek Wills noted, vcard is a finicky format, but the above worked for me.

So if Foo = my site users, and my slug is bitter-pill, pointing or linking to /card/bitter-pill/ would bring up a system box asking if you’d like to add my info to your address book. Don’t bother trying it here, though, as I haven’t changed this site over to Django yet.

Of course, if you wanted a bunch of people, just call an object list in the URL and adjust the template accordingly.

And icalendar works pretty much the same. Just set the mimetype to text/calendar.

3 Responses to “Stupidly simple microformat syncing with Django’s generic views.”

  1. site admin Says:

    You don’t have to touch the generic view. Was it the line in urls.py that was confusing? For those who aren’t really that familiar with Django, let me break it down:

    (r'^card/(?P[-\w]+)/$', - this is the url for the user. Slug is a urlized version of the thing you’re showing a card of. So, if the infor for the card is for “The Bitter Pill”, the slug version would be bitter-pill.

    'django.views.generic.list_detail.object_detail',
    - tells django to use it’s built in detail view
    dict(queryset=Foo.objects.all(),
    - now we’re passing some info to the detail view in a dict. First we tell it to use the Foo object, which “The Bitter Pill” should be part of. In the real world, Foo would probably be “Contacts” or “Users” or something like that.
    slug_field='slug', - tells the generic detail view what the Foo bbjects slug field is named. Most times, it’s “slug’
    template_name="microformats/vcard.html", - the location of the template I want to use
    mimetype="text/x-vcard") ), - and give it a the appropriate mimetype so it renders as a vcard.

  2. Paul Says:

    For what it’s worth, I’ve got a snippet that is a decent example of using vObject/vCard with Django, though your installation problems may make it moot… http://www.djangosnippets.org/snippets/58/

  3. site admin Says:

    Paul, I think vObject is a great way of doing this, and may be less fragile than my method. I like mine because I could do ical as easy as vcard, but troubles installing vObject was the real dealbreaker.