Thanks to this year’s community survey we have some data on this question. 94% of developers use Django Templates, and 18% use Jinja2. So most people seem to be happy enough with the default engine, or will use Jinja2 where it makes sense.
Not only am I “happy” with the default engine, I find it far superior than any of the other environments in which I’ve worked.
Personally, I really appreciate how Django handles this. I’ve spent too much time in the Java world in applications where the code logic is split between multiple layers and it’s incredibly frustrating to have to find out where some data element on the page is actually being retrieved or calculated.
I like the concept that all your data needs to be aggregated in your view and prepared prior to rendering the HTML. (It has also made it easier and cleaner for us to reuse some of those views when we want to generate something other than HTML.)
I think it’s a huge plus to have a templating language that actually tries to make it difficult to do things that end up being a maintenance nightmare.
But I would like to get an exception if an unknown variables gets accessed, since this means
(my point of view) that there is an error in the code. And you know “errors should never pass silently”.
I disagree with this. I consider the ability of Django to ignore undefined references to be a strength.
The benefit of doing this is that it allows us to make our templates a lot more generic and flexible with a minimum of additional work.
To say that an undefined variable is an error, means that every variable would need to be defined in every view rendering a template which could be a significant amount of additional work.
The alternative would be adding if tags around every optional component - which would require an additional directive, since the current templating language doesn’t have a separate if exists type of construct.
With the idea that all undefined variables is an error, something like:
{% if group_name %} </optgroup>{% endif %}
(in django.forms.templates.django.forms.widgets.select) wouldn’t even be valid without ensuring that every context that ends up rendering the select widget directly or indirectly has a goup_name defined at that layer of the context.
If there would be no demand for this, the snippet would not spread.
I am very opinionated concerning “error should never pass silently”. For me it is an error,
and I want to see an exception, not an empty string. It is like a shell script which
just executes the next line if one line fails. Sorry, I can’t build reliable products with it.
But I am very happy that Django is unopinionated here. You can use the default, or
you can use the “missing means error” approach.