admin管理员组文章数量:1122826
I have a template file letter.txt
in the format
Hello {{ first_name }} {{ last_name }}!
(In reality there are many more variables than these two, but for simplicity I'll stick with only first_name
and last_name
.)
This works nicely with a call like
from jinja2 import Environment, FileSystemLoader
environment = Environment(loader=FileSystemLoader("./"))
template = environment.get_template("letter.txt")
template.render(first_name='Jane', last_name='Doe')
Now if I have a list of names that should appear, like in a form letter, I need to do the following VERY verbose with
statement in the form_letter.txt
template file which includes the original untouched letter.txt
template.
{% for person in people %}
{% with first_name=person.first_name, last_name=person.last_name %}
{% include 'letter.txt' %}
{% endwith %}
------8<---cut here------------
{% endfor %}
and rendering the template via:
template = environment.get_template("form_letter.txt")
template.render(people=[{'first_name': 'Jane', 'last_name': 'Doe'},
{'first_name': 'Bob', 'last_name': 'Builder'},
{'first_name': 'Sara', 'last_name': 'Sample'}])
Creating and possibly having to expand the with
statement by hand is cumbersome and error prone. Is there a better way to "create a namespace inside a template" automatically from key/value of a dict like object? Like {% with **person %}
or something similar?
I have a template file letter.txt
in the format
Hello {{ first_name }} {{ last_name }}!
(In reality there are many more variables than these two, but for simplicity I'll stick with only first_name
and last_name
.)
This works nicely with a call like
from jinja2 import Environment, FileSystemLoader
environment = Environment(loader=FileSystemLoader("./"))
template = environment.get_template("letter.txt")
template.render(first_name='Jane', last_name='Doe')
Now if I have a list of names that should appear, like in a form letter, I need to do the following VERY verbose with
statement in the form_letter.txt
template file which includes the original untouched letter.txt
template.
{% for person in people %}
{% with first_name=person.first_name, last_name=person.last_name %}
{% include 'letter.txt' %}
{% endwith %}
------8<---cut here------------
{% endfor %}
and rendering the template via:
template = environment.get_template("form_letter.txt")
template.render(people=[{'first_name': 'Jane', 'last_name': 'Doe'},
{'first_name': 'Bob', 'last_name': 'Builder'},
{'first_name': 'Sara', 'last_name': 'Sample'}])
Creating and possibly having to expand the with
statement by hand is cumbersome and error prone. Is there a better way to "create a namespace inside a template" automatically from key/value of a dict like object? Like {% with **person %}
or something similar?
1 Answer
Reset to default 2Here's a slightly less verbose version, using set
keyword:
{% for person in people %}
{% set first_name, last_name = person.values() %}
{% include 'letter.txt' %}
------8<---cut here------------
{% endfor %}
You could instead refer to values directly: {% set first_name, last_name = person['first_name'], person['last_name'] %}
but that does not make it much more concise than your original code.
Another approach could be to change the data structure and infer the semantics based on the structure itself
template = environment.get_template("form_letter.txt")
print(template.render(people=[('Jane', 'Doe'),
('Bob', 'Builder'),
('Sara', 'Sample')]))
{% for person in people %}
{% set first_name, last_name = person %}
{% include 'letter.txt' %}
------8<---cut here------------
{% endfor %}
The structure is trivial enough that it is obvious what each field represents and tuples guarantee order regardless of version. For more complex objects you might consider named tuples, dataclasses etc:
from jinja2 import Environment, FileSystemLoader
from collections import namedtuple
environment = Environment(loader=FileSystemLoader("./"))
Person = namedtuple('Person', ['first_name', 'last_name'])
template = environment.get_template("form_letter.txt")
print(template.render(people=[Person(**el) for el in [{'first_name': 'Jane', 'last_name': 'Doe'},
{'first_name': 'Bob', 'last_name': 'Builder'},
{'first_name': 'Sara', 'last_name': 'Sample'}]]))
Ultimately there is no single solution that is good for all purposes.
本文标签: pythonAlternative to quotwithquot template command for loopsStack Overflow
版权声明:本文标题:python - Alternative to "with" template command for loops - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736310426a1934373.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
environment
is not defined. – matszwecja Commented Nov 21, 2024 at 13:46