For Django's default template language, does it still have these limitations?
1. Brackets aren't allowed to help with boolean expressions like {% if a and (b or c) %}
2. You can't do basic arithmetic like {{ x * 2 }}, but you're allowed to do {{ x | add:"2" }}. There's hacks to multiply using {% widthratio a 1 b %} or division with {% widthratio a b 1 %} though (https://stackoverflow.com/questions/18350630/multiplication-...).
3. You can't assign expressions to variables like {% with x = a or b %}, so you have to repeat yourself.
4. You can't capture HTML generated from template code in a variable to pass into a partial template to write slots-style HTML components e.g. {% capture x %}Hello {{ username }}{% endcapture %}{{ include "partials/header.html" with body_html=x }}.
5. You can't pass variables to model methods.
I understand there's a philosophy that templates shouldn't contain complex logic, but I find the above pretty arbitrary and leads to code that's harder to maintain. Addition is okay but not multiplication? Boolean logic is okay but not with brackets? I often have to puzzle out some way to get my code to work that goes against what I'd normally want to do, some I'm forced to duplicate template code because you can't put expressions in variables or move basic one-off logic into views (which has poor locality https://htmx.org/essays/locality-of-behaviour/ and makes it harder to move template snippets between pages).
It's like hiding the kitchen knives because they might be misused.
Is Jinja2 a practical alternative or there's friction to using it?
The migration is fairly simple and well documented.
The problem may be the lack of jinja support for 3rd party django apps (mostly legacy). So make sure they support it first.
> Is Jinja2 a practical alternative or there's friction to using it?
jinja2 is drop in by changing the template backend. You can actually run both at the same time (just can't mix them, ofc).
https://docs.djangoproject.com/en/6.0/topics/templates/