107

Using Django templating engine I can include another partial template while setting a custom context using named arguments, like this:

{% include "list.html" with articles=articles_list1 only %}
{% include "list.html" with articles=articles_list2 only %}

As you may be supposing, articles_list1 and articles_list2 are two different lists, but I can reuse the very same list.html template which will be using the articles variable.

I'm trying to achieve the same thing using Jinja2, but I can't see what's the recommended way, as the with keyword is not supported.

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
NiKo
  • 11,215
  • 6
  • 46
  • 56

5 Answers5

160

Jinja2 has an extension that enables the with keyword - it won't give you the same syntax as Django, and it may not work the way you anticipate but you could do this:

{% with articles=articles_list1 %}
    {% include "list.html" %}
{% endwith %}
{% with articles=articles_list2 %}
    {% include "list.html" %}
{% endwith %}

However, if list.html is basically just functioning as a way to create a list then you might want to change it to a macro instead - this will give you much more flexibility.

{% macro build_list(articles) %}
    <ul>
        {% for art in articles %}
            <li>{{art}}</li>
        {% endfor %}
    </ul>
{% endmacro %}

{# And you call it thusly #}
{{ build_list(articles_list1) }}
{{ build_list(articles_list2) }}

To use this macro from another template, import it:

{% from "build_list_macro_def.html" import build_list %}
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
76

This way you can pass multiple variables to Jinja2 Include statement - (by splitting variables by comma inside With statement):

            {% with var_1=123, var_2="value 2", var_3=500 %}
                {% include "your_template.html" %}
            {% endwith %}
pymen
  • 5,737
  • 44
  • 35
48

For readers in 2017+, Jinja as of 2.9 includes the with statement by default. No extension necessary.

http://jinja.pocoo.org/docs/2.9/templates/#with-statement

In older versions of Jinja (before 2.9) it was required to enable this feature with an extension. It’s now enabled by default.

Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245
  • Well I find myself in 2017 and it doesn't work. Bother with providing a link? – Pithikos Jul 20 '17 at 07:38
  • 2
    @Pithikos http://jinja.pocoo.org/docs/2.9/templates/#with-statement "In older versions of Jinja (before 2.9) it was required to enable this feature with an extension. It’s now enabled by default." – Yuji 'Tomita' Tomita Jul 21 '17 at 02:43
12

Updated 2021+

Included templates have access to the variables of the active context by default. For more details about context behavior of imports and includes, see Import Context Behavior.

From Jinja 2.2 onwards, you can mark an include with ignore missing; in which case Jinja will ignore the statement if the template to be included does not exist. When combined with with or without context, it must be placed before the context visibility statement. Here are some valid examples:

{% include "sidebar.html" ignore missing %}
{% include "sidebar.html" ignore missing with context %}
{% include "sidebar.html" ignore missing without context %}
Rami Alloush
  • 2,308
  • 2
  • 27
  • 33
  • 1
    Can you explain what is the difference between `with context`, `without context`, and no statement (for Jinja2 used with Django)? Also versions without `ignore missing`? – Adam Jagosz Feb 21 '23 at 12:21
2

Another option, without plugins, is to use macros and include them from another file:

file macro.j2

{% macro my_macro(param) %}
  {{ param }}
{% endmacro %}

file main.j2

{% from 'macro.j2' import my_macro %}

{{ my_macro(param) }}
Dany
  • 4,521
  • 1
  • 15
  • 32