I have the following variables to use in my Jinja template:
list_python_version = [3, 9]
all_python_version = [
[3, 8],
[3, 9],
[3, 10],
[3, 11],
[3, 12]
]
Is there a way to use a combination of Jinja filters and tests so it iterates over all_python_version
, checks that both the first and second elements of the list are greater or equal than the elements of list_python_version
, and when the conditions are met, it generates the string for MAJOR.MINOR
version and joins all that are valid in a single string?
This way, considering the variables above, the rendered template should give 3.9, 3.10, 3.11, 3.12
?
I have tried the following expression:
{{
all_python_version |
select('[0] >= minimal_python_version[0] and [1] >= minimal_python_version[1]') |
join('.') |
join(', ')
}}
But it will fail since the select
filter asks for a function, and so far I have not found in Jinja's documentation any hint as to how we can use conditionals to filter values inside an expression.
Alternatively, the solution could encompass a for
loop in Jinja, but I need the string to be rendered in one line, and if we do:
{% for version in all_python_version %}
{% if version[0] >= list_python_version[0] and version[1] >= list_python_version[1] %}
{{ version[0] ~ '.' ~ version[1] ~ ',' }}
{% endif %}
{% endfor %}
Each version will render in its own line, with the last ,
also being rendered.
Is there a way to do get the versions to be rendered in a single line in pure Jinja and its plugins?
Conveniently enough, since Jinja allows you to access elements of a list via both list[0]
and list.0
, this means that you can actually use a dictionary filter on a list.
And selectattr
is just the filter we need here, since it allows to select items out of a list of dictionaries based on a property of those dictionaries.
Still, we cannot properly fit a logical and
in there, so we'll need to split the logic in two:
So, we end up with a quite lengthy:
{{
all_python_version
| selectattr(0, '==', list_python_version.0)
| selectattr(1, '>=', list_python_version.1) | list
+ all_python_version | selectattr(0, '>', list_python_version.0) | list
}}
The snippet
{%- set list_python_version = [3, 9] -%}
{%- set all_python_version = [
[3, 8], [3, 9], [3, 10], [3, 11], [3, 12],
] -%}
{{
all_python_version
| selectattr(0, '==', list_python_version.0)
| selectattr(1, '>=', list_python_version.1) | list
+ all_python_version | selectattr(0, '>', list_python_version.0) | list
}}
Would yield:
[[3, 9], [3, 10], [3, 11], [3, 12]]
Then to join everything together, use a combination of map
and join
in the list of lists and a simple join
in the resulting list:
{{
(
all_python_version
| selectattr(0, '==', list_python_version.0)
| selectattr(1, '>=', list_python_version.1) | list
+ all_python_version | selectattr(0, '>', list_python_version.0) | list
) | map('join', '.') | join(', ')
}}
Giving
3.9, 3.10, 3.11, 3.12