345

I would like to know how can I set a variable with another variable in jinja. I will explain, I have got a submenu and I would like show which link is active. I tried this:

{% set active_link = {{recordtype}} -%}

where recordtype is a variable given for my template.

davidism
  • 121,510
  • 29
  • 395
  • 339
MyTux
  • 3,459
  • 2
  • 15
  • 4
  • 41
    Folks landing here from Google: you will probably be primarily interested in the [official docs on the `set` tag](http://jinja.pocoo.org/docs/latest/templates/#assignments), rather than the specific syntax mistake made by the asker here or how to fix it, which is what the top answers here and at the linked duplicate address. – Mark Amery Mar 03 '19 at 20:33

4 Answers4

663

{{ }} tells the template to print the value, this won't work in expressions like you're trying to do. Instead, use the {% set %} template tag and then assign the value the same way you would in normal python code.

{% set testing = 'it worked' %}
{% set another = testing %}
{{ another }}

Result:

it worked
Soviut
  • 88,194
  • 49
  • 192
  • 260
  • 3
    if my variable is dict what now {% set dict.key = 'test' %} don't work – Ib33X Nov 11 '11 at 11:19
  • A deleted answer also included this link, which serves as supplementary information to this answer: http://jinja.pocoo.org/docs/tricks/#highlighting-active-menu-items – Pascal Jul 12 '16 at 07:37
  • can we create a global jinja variable and use it throughout the html file in which we embed the jinja variable? @Soviut – Sri Test Jun 19 '20 at 12:48
  • To further illustrate by extending this example: `{% set another = testing + " flawlessly" %}` `{{ another }}` Result: `it worked flawlessly` – LunkRat Jul 01 '22 at 15:14
  • 1
    @LunkRat It is recommended to use `~` to concatenate strings, rather than `+` (see https://jinja.palletsprojects.com/en/2.11.x/templates/#math) – Jean-Francois T. Jan 28 '23 at 07:49
93

Nice shorthand for Multiple variable assignments

{% set label_cls, field_cls = "col-md-7", "col-md-3" %}
pymen
  • 5,737
  • 44
  • 35
30

Just Set it up like this

{% set active_link = recordtype -%}
Chad Pierce
  • 309
  • 3
  • 2
  • 10
    Why specifically like so (the minus sign at the end but not at the beginning)? This would remove trailing but not leading whitespace, if I am not mistaken. To what end? – Leonid Nov 07 '16 at 06:00
  • 29
    Its in the original question ¯\\_(ツ)_/¯ – Graham P Heath Apr 25 '18 at 19:05
  • 7
    The minus sign - appended to either the start or end of a statement (e.g. {%- -%}) tells Jinja to strip the new line that follows it. see https://www.webforefront.com/django/usebuiltinjinjastatements.html – Gevorg Hakobyan Jul 01 '21 at 11:38
16

You can do this with the set tag. See the official documentation.

For example,

{% set foo = "bar" %}
{{ foo }}

outputs

bar

Note: there are scoping issues which means that variable values don’t persist between loop iterations, for example, if you want some output to be conditional on a comparison between previous and current loop values:

{# **DOES NOT WORK AS INTENDED** #}

{% set prev = 0 %}
{% for x in [1, 2, 3, 5] %}
{%- if prev != x - 1 %}⋮ (prev was {{ prev }})
{% endif -%}
{{ x }}
{%- set prev = x %}
{% endfor %}

prints

1
⋮ (prev was 0)
2
⋮ (prev was 0)
3
⋮ (prev was 0)
5

because the variable isn’t persisted. Instead you can use a mutable namespace wrapper:

{% set ns = namespace(prev=0) %}
{% for x in [1, 2, 3, 5] %}
{%- if ns.prev != x - 1 %}⋮ (ns.prev was {{ ns.prev }})
{% endif -%}
{{ x }}
{%- set ns.prev = x %}
{% endfor %}

which prints

1
2
3
⋮ (ns.prev was 3)
5

as intended.

andrewdotn
  • 32,721
  • 10
  • 101
  • 130