Django Templates are not limited

shannon -jj behrens thinks that Django template language is limited - because it doesn't have functions with parameters to do html snippet reuse. Of course the official - and simplified - answer to this is, that Djangos template language is that simple by design, so that it can easily be learned by non-programmers (as often designers aren't necessarily programmers). This is a quite good reasoning, but I think it's a bit too simplified.

So here is the longer - more complete - answer to this accusition: the Django template language isn't limited at all. Yes, I know that the "include" and "block" tags aren't parameterizable and so aren't often that useful for more complex situations (at least if you don't want to end in namespace hell due to passing some template-globals in the context).

So what should you do if you notice that your templates would need more complex code? One way would be to precompute the data in the view function and pass it on via the context to the template - that way the template has the ready data and can directly present it.

But what to do if you can't precompute, because you are using generic views? You could wrap your generic view with your own code and call the original generic view in that function with the modified context. That way you have the same benefit as above - youre templates have the data readily available. If you have many view functions that all need the same context enrichment, you can write your wrapper as a decorator - and just decorate the generic views and use those decorated functions in your urlpatterns.

But what if even wrapping isn't the answer? Shouldn't there be some way to do more complex code without all that wrapping? Sure there is! The answer are custom template tags. This might sound like a bit of overkill, but believe me, writing some template tags isn't really that hard. There is documentation on using and extending the template system in python

An even easier way to write your own tags is to use the "simple_tag" or "inclusion_tag" helpers in django.template.Library. Those functions allow to build simple tags very easily - the inclusion tag will base it's output on some template snippet, so you can see it as a template function with paramerters. A lot of usage of custom templates is in the contrib/admin stuff.

The main problem with the newer stuff in the code is, there is documentation missing for it. Hopefully that will be solved over time. But please, if the next time someone tries to tell you that the Django Template Language is to primitive, don't believe him. The Django Template Language is easy to grasp for non-programmers - but it's very extensible for Python programmers. And you extend it in the language you like - in Python.

tags: Django, Programmierung, Python

Luke Plant Feb. 11, 2006, 5:34 p.m.

You can actually do a fair amount of 'pre-computing' using generic views if you pass the 'processors' argument - a list of functions that take the request argument and return a dictionary to merged into the context dictionary.

This can be slightly shorter than wrapping the generic views (though neither option is much code).

Maniac Feb. 12, 2006, 11:26 a.m.

Even better is to list your processor in TEMPLATE_CONTEXT_PROCESSORS in the settings file and be sure that all your contexts will include custom variables.

hugo Feb. 12, 2006, 11:48 a.m.

Sure, context processors are a real nice thing - but they can only work if all view functions have the same need. As soon as you need different handling in different view functions, you are back to wrapping or template tags. And especially template tags are often ruled out as to complex - which they aren't. I really think they should be first-class tools for Django devs, because it's often much more natural to just write a custom tag and use that in your templates than to try to "program" in the template language.

Many complaints about the "simpleness" of the Django template language can be answered with "write custom template tags". Of course some of those complaints can be answered by other stuff in Django, too ;-)