Jinja2: local / global variable

{% set disabled = '' %} {% for voter in record.voters %} {% if user == voter %} {% set disabled = 'disabled' %} {% endif %} {{ disabled }} # outputs: 'disabled' {% endfor %} {{ disabled }} # outputs: '' 

I have this template in Jinja2. I need the 'disabled' variable to be visible outside the 'for' loop. Is it possible?

+6
source share
4 answers

The easiest way to handle this is to move the logic that sets the disabled variable to your view function and send it to the template, ready for use. Mixing application logic with presentation is not a good idea, templates should receive data as learned as possible.

However, there is an ugly hack that does what you want is shown in the accepted answer to this question .

The solution includes a do extension for Jinja2 and using it to modify the global array. To enable the extension, follow these steps:

 app.jinja_env.add_extension('jinja2.ext.do') 

Here is a solution adapted to your example:

 {% set disabled = [] %} {% for voter in record.voters %} {% if user == voter %} {% do disabled.append(1) %} {% endif %} {% endfor %} {% if disabled %} disabled {% endif %} 
+10
source

You can use the / dict array, as Miguel suggests, but you do not need the extension do per se; you can install dummy var. I am using the following:

 {% set glob={} %} 

at the top and then in my code:

 {% set _ = glob.update({'disabled':True}) %} 

Variables _ are just a mannequin; you do not use it afterwards.

+6
source

By default, blocks may not access variables from external areas; you can override this with the scoped modifier as follows:

 {% for item in list scoped %} {% endfor %} 

See: http://jinja.pocoo.org/docs/templates/#block-nesting-and-scope

0
source

I understand that I am responding to an old thread. However, I started using Jinja recently and ran into a similar problem: I needed to count the number of print lines in nested loops. My solution was to transfer the counter variable to the class and pass the instance to the template. Similarly, you can use a wrapper class like

 class VoterStatus(object): def __init__(self, status='active'): self._status = status def set_disabled(self): self._status = 'disabled' def __str__(self): return self._status 

Change your template accordingly

 {% for voter in record.voters %} {% if user == voter %} {% status.set_disabled() %} {% endif %} {{ status }} # outputs: 'disabled' {% endfor %} 

Pass an instance of the status class to the template for rendering:

 tmplt.render(status=VoterStatus(), ...) 

... and Bob is your uncle.

0
source

Source: https://habr.com/ru/post/950537/


All Articles