Python templates – Django and Cheetah

Page style (CSS):

Python templates – Django and Cheetah

May 28th, 2008 by Eddie Sullivan

When writing web applications, sooner or later (usually sooner), everybody is going to need a template language. String-interpolation just doesn't cut it. We need a way to write something that is almost all text (or HTML, or XML, or whatever), but with some dynamic pieces thrown in.

Since this need is so universal, and the basic requirements are so easy to describe, many different groups of people have taken it upon themselves to create Yet Another Template Language. As developers, we can join the fray and roll our own, or we can wade through the myriad options available to us to find the one that meets our needs or philosophy. Those who use PHP or ASP pretty much have the choice made for them, since the languages themselves are glorified template processors. Python programmers have a lot more options.

Here I'm just going to focus on the two Python templating languages I have used in real applications: Cheetah and the Django templating engine. (Django, of course, is more than just templates, but the template subsystem can be used independently.) I use and enjoy both of these, but there are significant differences that are worth comparing and contrasting, when deciding which to use for your particular needs. There are other comparisons out there, including one by the Benevolent Dictator for Life himself (though that's a bit out of date and inaccurate). When choosing which to use, you should read as many opinions as you can, then make the decision yourself. Presented here are just my personal thoughts.

Syntax

Both of these languages are plain-text based, rather than XML based or any other format. This means it's easy to use them for creating formats that are not XML or HTML, like text or even code. It also means it's easy to forget to close a tag or to create non-compliant pages, so always be sure to test with HTML-Tidy or something like that.

The two languages are pretty similar in their syntax, and in my humble opinion, they're both pretty ugly.

Django uses {{ and }} to surround variables to be interpolated. These variables can be passed through a "filter" - a specially designed Python function - using a vertical bar |. One additional parameter can be passed to the filter using a colon :. So, for example, to include a floating-point variable, expressed with two digits after the decimal point, you would write something like: {{ myVar|floatformat:2 }}. There is a lot of punctuation there, but you do get used to it.

Cheetah's variable interpretation looks more like how it's done in shell-scripting languages, with a dollar sign $ and optional brackets { and }, so it looks like $myVar or ${myVar}.

They both also allow some logic and flow control. Django has "tags" surrounded by {% and %}. Cheetah has "directives" that start with # and end with either another # or a newline. Cheetah also allows embedding pure Python using ASP-like <% and %>.

Aesthetically, I prefer the dollar signs of Cheetah for variables, but prefer Django's approach to the logic sections. Either way, you'd better do some finger exercises to limber up before typing.

Philosophy

The major philosophical difference between Cheetah and Django templating is the amount of programming power each system makes available in the templates themselves. In some circles, there is a priority placed on separation of content from code, often going so far as to delegate the tasks to different people. According to this philosophy, designers should work on the presentation, writing HTML and so on, and programmers should work on the logic and back-end behavioral aspects. In the real world, this is an impossible division, because the two are often so closely intertwined, and the very existence of template languages is an admission of this fact. A template is, by definition, a mixture of logic and content. The difference is in the extent of this mixture.

Cheetah makes the whole Python interpreter available to the template writer. Django provides a simple set of "tags" and "filters," allowing limited functionality. These can be extended through "custom tags" and "custom filters." According to the Django documentation, this limitation is intentional, and is meant to limit the mixing of logic and content.

In practice, the mixing happens either way. In Cheetah, it is easy to end up with a whole lot of Python code in the middle of your HTML file, which some would consider inappropriate. In Django, it is easy to wind up constructing pieces of HTML in your code files and passing them to the template processor as parameters. On one side, the Python infects the HTML; on the other side, the HTML infects the Python.

Personally, I'm a one-man development team, so I have no problem with mixing logic and content, either philosophically or pragmatically. I find the Cheetah approach leads to less total code required, plus I'm a big believer in the "we're all adults here" approach to programming, so I prefer the power that Cheetah offers. However, I can understand if people want to limit what logic is available in templates, if they are meant to be edited by designers, marketers, or pointy-haired bosses. In that case, Django might make more sense.

What I use

As I said above, I use both. I use the Django templating system when I am working within the framework of Django. Django does allow you to use any templating system you like, but then you lose the power of the built-in generic views and context processors. I use Cheetah when I don't need all the power of the Django framework (the database access layer, URL dispatcher, authentication, etc.).

I have a slight preference for Cheetah, but they're both very useful. I hope this post provides some help for those choosing between the two.

2 Responses to “Python templates – Django and Cheetah”

  1. Goodrone says:
    mako templates are really exciting :) something like Cheetah, with full power of embedded Python code. mako templates are used by default in Pylons framework
  2. Hi
    The big thing for me is the ease of generating non-HTML markup.
    Because I am using Curl (developers.curl.com) with a MIME type of 'text/vnd.curl' I like having just the $ sigil to work with on variable names and having code behind the #set #if #for etc.
    It gives a very readable result given Curl's use of { and }
    I found Eric Florenzano's note helpful for using Django + Cheetah, which is what I have opted for now.
    Anything to get me away from XML-style tags ;-)

Leave a Reply