UPDATE: Here’s a smart drop-in app that integrates Jinja2 and Django, with a minimum of fuss. By default, it inspects the filenames of your templates to determine which rendering engine to use. So if you want to use Jinja for a particular template, name it “foo.jinja.html”, for example. Otherwise, you just leave the template as-is, and the default Django rendering engine will do its thing.
Although I haven’t explored this feature, the author suggests you can use any other logic you’d like to determine when to enable Jinja rendering, such as a tag at the top of the file, for example. Me, I’m satisfied with the filename extension, because, hey, that’s about as simple as it gets. Pretty, pretty clever.
Jinja2 is a real improvement over the standard Django template system. It has a number of useful features that the built-in Django templates just don’t have — especially when it comes to basic visual markup logic (elif statements, basic macros). Thankfully, Django is built to be pluggable and modular, and it’s not terribly difficult to get Jinja2 working with it.
When I wrote my first Jinja2-based app a couple of years ago, I did so using a little helper script I cobbled together from various Jinja2/Django-type pioneers, and the result was a workable — if a little hacky and kludgy — module that I could reuse in each of my apps. I import it in my views.py, and it gives me the most basic template-type methods like render_to_response and such. It’s limited, but I really haven’t had need for much else. (And when I’ve needed to expand its functionality, I have.) But it’s always felt like a temporary fix — a little incomplete and hackish. I took a look around recently to see if there were any other solutions that integrated Jinja2 into Django a little more gracefully and completely.
It wasn’t long before I found coffin — a library that’s more or less a port of Django’s template functionality, but using Jinja2′s rendering. Its real killer feature, IMO, is how easy it is to use Django template tags and filters within coffin — which is something you might not expect to need, but it’s very handy to have. For example, coffin includes a ton of useful tags and filters out of the box — like the super-useful {% spaceless %}. And you can easily add others, without having to write a complete port.
Coffin works a lot like my little helper module. You import it in every page, explicitly.
But I found something that I think is just a tad better: this fork of coffin. Its best feature is that it can be plugged in directly to Django’s native template loading system, so that it is integrated a little more neatly. All it takes is just a little adjustment to your project’s settings file:
TEMPLATE_LOADERS = (
'coffin.template.loaders.Loader',
)
JINJA2_TEMPLATE_LOADERS = (
‘django.template.loaders.app_directories.Loader’,
‘django.template.loaders.filesystem.Loader’,
)
The coffin template handling is enabled more or less transparently — using Django’s syntax while the templates are handled behind the scenes. Thus, in your apps, instead of this:
from coffin.shortcuts import render_to_response
You can use the usual Django syntax:
from django.shortcuts import render_to_response
Helpfully, this fork also allows you to turn off Jinja2 rendering on an app-by-app basis, with a simple tuple in your settings file. So it’s easy to have, say, the Django debug toolbar running with Django templates alongside your app that uses Jinja2 templates.
I really like this approach, mainly for the reason that enabling Jinja2 can be enabled — and overridden — completely from the settings file.
I don’t have a strong opinion about the pros and cons of these two approaches, but I’ll be trying out the template-loader fork of coffin to see how well it runs and how easy it is to use. I’ll be curious to see if anyone has any input as to whether the template-loader approach has any design concerns that I haven’t considered.
Meanwhile, give it a shot! Enjoy.