Jinja2中的变量内部变量

4

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. 问题

我在循环中有重复的 Goddessgreatest of all time!。我能不能不使用重复?


3. 未获得帮助

3.1. 相似问题

这个这个这个许多其他 Stack Overflow 问题。

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())

I get traceback:

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())

我的尝试中出现了重复。
1个回答

7

您正在寻找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 %}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接