2013-07-29 17 views
6
{% set disabled = '' %} 
{% for voter in record.voters %} 
    {% if user == voter %} 
     {% set disabled = 'disabled' %} 
    {% endif %} 
    {{ disabled }} # outputs: 'disabled' 
{% endfor %} 
{{ disabled }} # outputs: '' 

Mam ten szablon w Jinja2. Potrzebuję zmiennej "wyłączonej", aby była widoczna poza pętlą "dla". Czy to możliwe?Jinja2: zmienna lokalna/globalna

Odpowiedz

10

Najprostszym sposobem radzenia sobie z tym jest, aby przenieść logika, która ustawia zmienną disabled do funkcji widoku i wysyła ją do szablonu gotowego do użycia. Łączenie logiki aplikacji z prezentacją nie jest dobrym pomysłem, szablony powinny otrzymywać dane w możliwie największym stopniu.

To powiedziawszy, istnieje brzydki hack, który sprawia, że ​​to, co chcesz, pokazano w zaakceptowanej odpowiedzi na this question.

Rozwiązanie polega na włączeniu rozszerzenia do dla Jinja2 i użyciu go do zmodyfikowania tablicy globalnej. Aby umożliwić stosowanie rozszerzeń:

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

Oto rozwiązanie dostosowane do przykładu:

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

thx . Już poprawiłem swój kod i tak jak na początku zasugerowałeś. –

0

Domyślnie blokach nie mogą uzyskać dostęp do zmiennych z zakresów zewnętrznych, można to zmienić za pomocą modyfikatora scoped tak:

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

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

+1

To się nie udało! "Scoped" działa dla bloków nie dla pętli –

+0

@ c00p3r.web w takim przypadku proponuję otworzyć problem dla jinja2, ponieważ wydaje się, że funkcja będzie pożądana: https://github.com/mitsuhiko/jinja2/issues –

6

Można używać tablicy/dict jak Miguel sugeruje, ale nie trzeba rozszerzenie zrobienia per se ; możesz ustawić atrapę var. Używam następujących czynności:

{% set glob={} %} 

na górze, a następnie w moim kodu:

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

W _ zmienne to tylko atrapa, nie używać go później.

0

Zdaję sobie sprawę, że odpowiadam na stary wątek. Jednak ostatnio zacząłem używać Jinja i wpadłem na podobny problem: musiałem policzyć ilość wydrukowanych wierszy w zagnieżdżonych cyklach. Moim rozwiązaniem było zawijanie zmiennej licznika w klasie i przekazywanie instancji do szablonu. Podobnie, można użyć klasy otoki, tak jak

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

    def set_disabled(self): 
     self._status = 'disabled' 

    def __str__(self): 
     return self._status 

Modyfikacja szablonu odpowiednio

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

Przepuścić instancji klasy status do szablonu do renderowania:

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

... a Bob jest twoim wujkiem.