The Jinja do Extension: Executing Expressions in Your Templates
n
{{ ... }} to display data, but what if you need to act? You can’t just call a method with side effects inside a variable expression. This is where the **expression-statement extension** and its associated `do` tag come into play, giving you a controlled way to execute code that doesn’t produce output.nnnn
nn
What is the do Tag?
nThe `do` tag, written as {% do ... %}, is a specialized tag that allows you to execute an expression without printing the result. It’s essentially the non-printing counterpart to the standard `{{ … }}` variable expression. While `{{ some_var }}` evaluates `some_var` and injects its value into the HTML, `{% do some_function() %}` evaluates `some_function()` but outputs nothing. This makes it perfect for situations where you need to act—such as modifying a variable or calling a method—for its side effects.nnThis functionality is not part of Jinja’s core by default because it blurs the line between logic and presentation. A well-designed template should primarily focus on displaying data, not manipulating it. By making `do` an optional extension, Jinja gives developers the choice to use this power when needed, but only after consciously enabling it.nn
nn
nn
A Practical Use Case: Modifying Lists
nA classic and highly useful application of the `do` tag is for modifying data structures passed to the template. Imagine you have a list of navigation items, and in a specific template, you need to add a new item to that list dynamically. You could do it cleanly with the `do` tag:n
n{# Assume 'navigation' is a list passed to the template #}n{% do navigation.append('a string') %}<ul>n{% for item in navigation %}n<li>{{ item }}</li>n{% endfor %}n</ul>nIn this example, the `{% do … %}` tag calls the `append()` method on the `navigation` list. This modifies the list in place without producing any output. The subsequent `for` loop then iterates over the now-modified list, correctly rendering all the items, including the one you just added. Without the `do` tag, you would have to perform this modification in your application’s Python code before rendering the template, which might not be ideal in all situations.nn
nn
nn
Why It’s an Extension, Not a Core Feature
nThe `do` tag is not meant to be a replacement for all business logic. Placing complex data manipulation inside templates can lead to code that is difficult to read, test, and maintain. Jinja’s core philosophy encourages keeping logic in your Python application and passing prepared data to the template. The `do` extension is a valuable tool for those small, controlled manipulations that are more convenient to perform directly within the template. It’s a pragmatic compromise that gives you flexibility while still encouraging good design practices. By having to explicitly load it, developers are reminded of the importance of separating concerns.nn
nn
nn
n
