I need to generate a document with letter indices, like this one:
Channels:
- A: Foobar item
- B: Foobaz item
- ...
I have input file with Foobar
, Foobaz
, etc and I want jinja2
to generate it with indeces A
, B
, etc from template file, like this:
Channels: {% for item in items %}
- {{ None | next_id }}: {{ item.name }} item {% endfor %}
I want to use Python Generator with this template, but I can't find the working solution, the latest code version is:
...
# Simple letters generator
def idgen():
value = 'A'
while True:
yield value
value = (chr(ord(value)+1))
gen = idgen()
# Function to be used as Custom Filter
# https://jinja.palletsprojects.com/en/master/api/#writing-filters
# I don't know is it implementable without function, just with generator
def next_id():
return next(gen)
env = Environment(loader=FileSystemLoader(template_dir))
env.filters['next_id'] = next_id
template = env.get_template(template_filename)
# items = [{'name': 'Foobar'}, {'name': 'Foobaz'}]
print(next_id()) # To see if generator iterates
print(template.render(items=items))
print(next_id())
And corresponding output is:
B
Channels:
- A: Foobar item
- A: Foobaz item
C
Need your help, hivemind.
I found just one workaround so far. Assume that Jinja uses some kind of caching/optimization depending on Custom Filter's function input:
Here:
B
Channels:
- A: Foobar item
- A: Foobaz item
C
So the most obvious workaround is to send new input every time, i.g. {{ loop.index | next_id }}
:
Template:
Channels: {% for item in items %}
- {{ loop.index | next_id }}: {{ item.name }} item {% endfor %}
Result:
Channels:
- A: Foobar item
- B: Foobaz item