I can't set use variable inside variable in my Jinja2 example.
Solution must be Pelican-compatible.
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!
"""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())
I have duplicate Goddess
and greatest of all time!
in loops. Can I don't use duplicates?
This, this, this and many others Stack Overflow questions.
For example, this code doesn't work:
"""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 '{'
For preventing XY Problem I post truncated real code:
<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>
The example shows where static is and where variables.
"""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())
Duplicates in my attempt.
You are looking for Jinja macros; functions that produce output when called:
{% 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 %}
Demo:
>>> 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!
or, applying this to your real-life example:
{% 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 %}