Sunday, March 29, 2009

Cleaner and Cleaner

Re: yesterday's post, I read a little more of the excellent and free Django book this morning, and I realized that template includes don't have to be hard-coded. They can use variables.

Woohoo! This lets me move all my special-case logic into the Python code. Instead of nested {% if %} statements in the template, I'm doing a simple list lookup in Python. Then I use one {% include d.template %} to pull the results into the template. This Django stuff cleans up real nice.

Saturday, March 28, 2009

The Template Made Me Do It

I've been doing a little Django lately. Django's template language isn't Python; it's a somewhat Pythonic template language, and it's limited by design. At first, it frustrated me; after a brief battle, it surprised me.

My template was pretty simple: generate a monthly calendar page. Every day gets the same HTML, except for three special cases: first Wednesday of the month, other Wednesdays, and all Fridays.

In my first version, I passed a list of datetime.date objects in the context. The template for-looped through the list, and did things like

{% ifequal d.isoweekday 3 %}

All by itself, that's mildly evil - the hard-coded magic number, though I can probably remember that isoweekday() starts counting at Monday == 1. Then I started nesting the if-else tags, and things got messy quickly. The Wednesday case, the Friday case, the first-Wednesday case: frustration. I wanted Python at my fingertips, not this crippled template language.

Which, of course, was the answer. I needed better abstractions for the template, and Python was the right place to create them. I subclassed datetime.date and added the methods I needed: is_wednesday(), is_first_wednesday(), is_friday(), is_special()

Which let me write reasonable template code like

{% if d.is_special %}
    {% if d.is_first_wednesday %}

And then the surprise: I realized that fixing the messy template had also made my Python code cleaner. I ended up with a nice little app-specific date class, unit tests and everything. That was the right thing to do, but I hadn't bothered till I needed it for the template. The limitations of the template language drove the refactoring.

And that makes me think that limiting the template language was a very good idea indeed.

Monday, March 2, 2009

Do Be Do Be Done

Do you ever feel like the big-name web frameworks have grown too much, that they're bloated from an endless diet of new features?

Here's fast relief for that bloated feeling: Sinatra, a lightweight Ruby web framework. Minimal docs, but $10 gets you traction from a couple of excellent screencasts.