I have a custom tag in Jinja2 that I want to output something only the first time that it is called. So say I have the following template:
1. {% only_once %}
2. {% only_once %}
3. {% only_once %}
I want the output to be:
1. "I only get printed once!"
2.
3.
I'm guessing the best way to do this is to set a flag in the context of the template to track whether I've already printed something or not. Here's a code sample, but is this right?
class OnlyOnceExtension(Extension):
tags = set(['only_once'])
@contextfunction
def parse(self, context, parser):
if hasattr(context, 'my_flag') and context.my_flag:
return Output("")
else:
return Output("I only get printed once!")
Is that correct? I read some stuff about the context is immutable, so will this not work? (see http://jinja.pocoo.org/2/documentation/api and search for immutable)
If you want to do it purely with Jinja you can just check the loop.index variable in that fashion,
{% for bar in bars %}
{% if loop.index == 1 %}
Print me once
{% endif %}
Print me every time
{% endfor %}
My suggestion is to implement this in Python code:
class OnlyOnce(object):
def __init__(self, data):
self.data = data
self.printed = False
def __str__(self):
if self.printed is False:
self.printed = True
return self.data
return ''
Create an OnlyOnce
instance in your Python code and pass it to the template, and then every time you want to use it, just use {{ only_once }}
.
One thing I notice about a lot of people using Jinja is that they want to do things in a Django-ish way, that is, writing extensions. But Jinja's expressions/importing/whatever is powerful enough that you don't have to use extensions for everything.
And yes, using the context.my_flag
thing is a bad idea. Only the template gets to modify the context. EVER.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With