1. Summary
I can’t find, what is the correct syntax in Jinja2 for expressions like if any() in object
/if all() in object
.
2. MCVE
-
"""Jinja2 if any() in object MCVE.""" from jinja2 import Template KIRA_BLOCK = """ {% if 14 in range(1,5) or 4 in range(1,5) or 7 in range(1,5) %} Kira Goddess! {% endif %} """ print(Template(KIRA_BLOCK).render())
How can I get the same result without duplicate code?
3. Not helped
I tried searching for the answer to my question and similar examples in Google, GitHub and Jinja documentation
I didn’t understand how can I use Jinja built-in filters to solve my problem
I tried
select()
filter, as recommended in this answer on Stack Overflow. Like this:KIRA_BLOCK = """ {% if (14,4,7)|select|first in range(1,5) %} Kira Goddess! {% endif %} """
I tried to register a custom
any()
filter, as recommended in the same answer on Stack Overflow. Like this:"""Jinja2 if any() in object MCVE.""" from jinja2 import Environment from jinja2 import Template environment = Environment() environment.filters["any"] = any KIRA_BLOCK = """ {% if (14,4,7)|any in range(1,5) %} Kira Goddess! {% endif %} """ print(Template(KIRA_BLOCK).render())
4. Real example
For preventing XY problem:
I use similar templates in static site generator Pelican. Example:
{# [INFO] If any of the classes "attention", "caution" or "warning" exists in my article, I add specific styles #}
{% if "class=\"attenion\"" in article.content or if "class=\"caution\"" in article.content or if "class=\"warning\"" in article.content %}
<link rel="preload" href="path/to/css/third-party/Admonition/admonition-warning.min.css" as="style" onl oad="this.rel='stylesheet'">
{# [INFO] Elif all classes "faq", "help" and "question" exists in my article, I add another styles #}
{% elif "class=\"faq\"" in article.content and if "class=\"help\"" in article.content and if "class=\"question\"" in article.content %}
<link rel="preload" href="path/to/css/third-party/Admonition/admonition-question.min.css" as="style" onl oad="this.rel='stylesheet'">
{% endif %}
I don’t understand how to remove hard coding from these templates.
Thanks.
CodePudding user response:
I can’t find, what is the correct syntax in Jinja2 for expressions like
if any() in object
/if any() in object
.
That's not how the any()
function works in Python. You might write something like this:
if any(value == 4 for value in mylist):
...
The any()
function, as shown in the documentation, is equivalent to:
def any(iterable):
for element in iterable:
if element:
return True
return False
The above unfortunately doesn't translate well into Jinja, because Jinja doesn't support list/tuple comprehensions, without which the any()
function is much less useful.
Looking at what you're actually trying to do:
{#
[INFO] If any of the classes "attention", "caution" or
"warning" exists in my article, I add specific styles
#}
{% if "class=\"attenion\"" in article.content
or if "class=\"caution\"" in article.content
or if "class=\"warning\"" in article.content %}
<link rel="preload" href="path/to/css/third-party/Admonition/admonition-warning.min.css" as="style" onl oad="this.rel='stylesheet'">
{% endif %}
You could register a custom has_class
filter that looks like this:
def has_class(content, classnames):
return any(f'' in content for name in classnames)
And use it like this:
{#
[INFO] If any of the classes "attention", "caution" or
"warning" exists in my article, I add specific styles
#}
{% if article.content|has_class(['attention', 'caution', 'warning']) %}
<link rel="preload" href="path/to/css/third-party/Admonition/admonition-warning.min.css" as="style" onl oad="this.rel='stylesheet'">
{% endif %}