Переменная внутри переменной в Jinja2

1. Резюме

Я не могу установить переменную использования внутри переменной в моем примере с Jinja2.

Решение должно быть Pelican -совместимым.


2. MCVE

2.1. Ожидаемое поведение

Any text

    Goddess Kira greatest of all time!

    Goddess Kristina greatest of all time!


Another text

    Goddess Sasha greatest of all time!

    Goddess Katya greatest of all time!

2.2. моя попытка

"""Jinja2 nested variables example."""
from jinja2 import Template

KIRA_BLOCK = """
{% set first_list = ['Kira', 'Kristina'] %}
Any text
{% for name in first_list %}
    Goddess {{name}} greatest of all time!
{% endfor %}
{% set second_list = ['Sasha', 'Katya'] %}
Another text
{% for name in second_list %}
    Goddess {{name}} greatest of all time!
{% endfor %}
"""

print(Template(KIRA_BLOCK).render())

2.3. Проблема

У меня есть дубликаты Goddess и greatest of all time! в петлях. Могу ли я не использовать дубликаты?


3. Не помогло

3.1. Похожие вопросы

Это, это, это и < a href = "https://i.imgur.com/Lm25naW.png" rel = "nofollow noreferrer"> многие другие Вопросы о переполнении стека.

3.2. Вложенные переменные

Например, этот код не работает:

"""Jinja2 nested variables example."""
from jinja2 import Template

KIRA_BLOCK = """
{% set she_greatest = 'Goddess' {{name}} 'greatest of all time!' %}
{% set first_list = ['Kira', 'Kristina'] %}
Any text
{% for name in first_list %}
    {{she_greatest}}
{% endfor %}
{% set second_list = ['Sasha', 'Katya'] %}
Another text
{% for name in second_list %}
    {{she_greatest}}
{% endfor %}
"""

print(Template(KIRA_BLOCK).render())

Я получаю обратную связь:

Traceback (most recent call last):
  File "KiraJinja2.py", line 18, in <module>
    print(Template(KIRA_BLOCK).render())
  File "C:\Python37\lib\site-packages\jinja2\environment.py", line 945, in __new__
    return env.from_string(source, template_class=cls)
  File "C:\Python37\lib\site-packages\jinja2\environment.py", line 880, in from_string
    return cls.from_code(self, self.compile(source), globals, None)
  File "C:\Python37\lib\site-packages\jinja2\environment.py", line 591, in compile
    self.handle_exception(exc_info, source_hint=source_hint)
  File "C:\Python37\lib\site-packages\jinja2\environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Python37\lib\site-packages\jinja2\_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "<unknown>", line 2, in template
  File "C:\Python37\lib\site-packages\jinja2\environment.py", line 497, in _parse
    return Parser(self, source, name, encode_filename(filename)).parse()
  File "C:\Python37\lib\site-packages\jinja2\parser.py", line 901, in parse
    result = nodes.Template(self.subparse(), lineno=1)
  File "C:\Python37\lib\site-packages\jinja2\parser.py", line 888, in subparse
    self.stream.expect('block_end')
  File "C:\Python37\lib\site-packages\jinja2\lexer.py", line 384, in expect
    self.name, self.filename)
jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got '{'

4. Реальный пример

Для предотвращения проблемы XY я публикую усеченный реальный код:

4.1. Ожидаемое поведение

<div class="KiraCategory">First</div>

    <a onclick="KiraFunction(document.all.sitename.value, 'https://Alpha.com');" class="Foo">Alpha</a>

    <a onclick="KiraFunction(document.all.sitename.value, 'https://Bravo.ru');" class="Bar">Beta</a>


<div class="KiraCategory">Second</div>

    <a onclick="KiraFunction(document.all.sitename.value, 'https://Charlie.net');" class="Baz">Gamma</a>

В примере показано, где статические, а где переменные.

4.2. моя попытка

"""Jinja2 nested variables example."""
from jinja2 import Template

KIRA_BLOCK = """
{% set first_list = [
    ('https://Alpha.com', 'Foo', 'Alpha'),
    ('https://Bravo.ru', 'Bar', 'Beta')
] %}
<div class="KiraCategory">First</div>
{% for url, color, sitename in first_list %}
    <a onclick="KiraFunction(document.all.sitename.value, '{{url}}');" class="{{color}}">{{sitename}}</a>
{% endfor %}
{% set second_list = [
    ('https://Charlie.net', 'Baz', 'Gamma'),
] %}
<div class="KiraCategory">Second</div>
{% for url, color, sitename in second_list %}
    <a onclick="KiraFunction(document.all.sitename.value, '{{url}}');" class="{{color}}">{{sitename}}</a>
{% endfor %}
"""

print(Template(KIRA_BLOCK).render())

Дубликаты в моей попытке.


person Саша Черных    schedule 14.02.2019    source источник


Ответы (1)


Вы ищете Jinja макросы; функции, которые производят вывод при вызове:

{% macro she_greatest(name) -%}
    Goddess {{name}} greatest of all time!
{%- endmacro %}

{% set first_list = ['Kira', 'Kristina'] %}
Any text
{% for name in first_list %}
    {{ she_greatest(name) }}
{% endfor %}
{% set second_list = ['Sasha', 'Katya'] %}
Another text
{% for name in second_list %}
    {{ she_greatest(name) }}
{% endfor %}

Демо:

>>> from jinja2 import Template
>>> demo = '''
... {% macro she_greatest(name) -%}
...     Goddess {{name}} greatest of all time!
... {%- endmacro %}
...
... {% set first_list = ['Kira', 'Kristina'] %}
... Any text
... {% for name in first_list %}
...     {{ she_greatest(name) }}
... {% endfor %}
... {% set second_list = ['Sasha', 'Katya'] %}
... Another text
... {% for name in second_list %}
...     {{ she_greatest(name) }}
... {% endfor %}
... '''
>>> print(Template(demo).render())




Any text

    Goddess Kira greatest of all time!

    Goddess Kristina greatest of all time!


Another text

    Goddess Sasha greatest of all time!

    Goddess Katya greatest of all time!

или применив это к вашему примеру из реальной жизни:

{% macro kira_function_link(url, color, sitename) -%}
<a onclick="KiraFunction(document.all.sitename.value, '{{url}}');" class="{{color}}">{{sitename}}</a>
{%- endmacro %}

{% set first_list = [
    ('https://Alpha.com', 'Foo', 'Alpha'),
    ('https://Bravo.ru', 'Bar', 'Beta')
] %}
<div class="KiraCategory">First</div>
{% for url, color, sitename in first_list %}
    {{ kira_function_link(url, color, sitename) }}
{% endfor %}
{% set second_list = [
    ('https://Charlie.net', 'Baz', 'Gamma'),
] %}
<div class="KiraCategory">Second</div>
{% for url, color, sitename in second_list %}
    {{ kira_function_link(url, color, sitename) }}
{% endfor %}
person Martijn Pieters    schedule 14.02.2019