Using Declarative Syntax, Part 1

by Marty Alchin on November 10, 2007 about Django

A while back, I wrote a bit about my work on django-modular, and one of the comments pointed me to the Netvibes UWA. While that wasn’t the point of django-modular, it still looked like it would be reasonably easy to support in a way that would integrate well with a Django app.

One of the defining characteristics of Django is its declarative syntax, and I knew I wanted to incorporate it into this as well. The API seemed well-suited for it, and it would be a great way to make it very familiar to anyone experienced with Django.

So I’m starting a mini-series to explain how easy it can be to incorporate Django-style declarative syntax in your own app or framework. I’ll be using the Netvibes UWA as an example, but it should be clear how to use it for your own needs.

Identifying declarative syntax

Anyone familiar with Django should be able to identify what I mean by the term “declarative syntax,” but here are a couple examples to illustrate what we’ll need in order to build it ourselves:

from django.db import models
from django import newforms as forms

class Article(models.Model):
   title = models.CharField(max_length=255)
   content = models.TextField()

class Article(forms.Form):
   title = forms.CharField()
   content = forms.CharField(widget=forms.Textarea)

I tend to split this syntax apart into three essential components:

  1. A single module namespace to import

    While not essential for the functionality, having just one module to import makes it very easy to use the API in an app. Everything’s all in one place.

  2. A base class to specify in subclasses

    Since the syntax relies on declaring classes, a base class must be provided to make the whole thing work. Naming this properly helps with readability, too. Using an accurate noun is important here, to easily identify what the subclass represents.

  3. A set of attribute classes to instantiate

    The classes your API supports don’t need to be entirely made up of provided class instances, but there should be a set of common tools for subclasses to use. Naming is important here as well. I like to use Django’s pattern, by using two words: a suffix to describe the basic type of object, following a name specifying the exact nature of the object itself (for example, CharField)

With this in mind, and a quick glance at how the UWA declares preferences, here’s basically how I’d like the API to look. Keep in mind the concepts above, and notice how it fits in with the general feel of Django:

import widgets

class FeedReader(widgets.Widget):
   url = widgets.TextPreference("URL")
   item_count = widgets.RangePreference("How many items?", min=1, max=10, default=5)

There wil be more to it, of course, but that’s the basic idea.

That brief analysis is all I’ll cover for tonight, but there will be much more to follow. Keep an eye out for details on

Check in again tomorrow!