skyler
skyler

Reputation: 8348

Conditionally join a list of strings in Jinja

I have a list like

users = ['tom', 'dick', 'harry']

In a Jinja template I'd like to print a list of all users except tom joined. I cannot modify the variable before it's passed to the template.

I tried a list comprehension, and using Jinja's reject filter but I haven't been able to get these to work, e.g.

{{ [name for name in users if name != 'tom'] | join(', ') }}

gives a syntax error.

How can I join list items conditionally?

Upvotes: 21

Views: 24089

Answers (4)

Cristian Ispan
Cristian Ispan

Reputation: 764

If someone is trying to reject more than one value just try to write 'in' with list afterwards instead of 'equalto'/'sameas':

>>> import jinja2
>>> template = jinja2.Template("{{ items|reject('in', ['a','b'])|join(',') }}")
>>> template.render(users=['a', 'b', 'c'])
u'c'

Upvotes: 0

falsetru
falsetru

Reputation: 369164

Use reject filter with sameas test:

>>> import jinja2
>>> template = jinja2.Template("{{ users|reject('sameas', 'tom')|join(',') }}")
>>> template.render(users=['tom', 'dick', 'harry'])
u'dick,harry'

UPDATE

If you're using Jinja 2.8+, use equalto instead of sameas as @Dougal commented; sameas tests with Python is, while equalto tests with ==.

Upvotes: 25

N. Chamaa
N. Chamaa

Reputation: 1577

Another solution with "equalto" test instead of "sameas"

Use reject filter with equalto test:

>>> import jinja2
>>> template = jinja2.Template("{{ items|reject('equalto', 'aa')|join(',') }}")
>>> template.render(users=['aa', 'bb', 'cc'])
u'bb,cc'

Upvotes: 1

bendtherules
bendtherules

Reputation: 382

This should work, as list comprehension is not directly supported. Ofcourse, appropiate filters will be better.

{% for name in users if name != 'tom'%}
    {{name}}
    {% if not loop.last %}
         {{','}}
    {% endif %}
{% endfor %}

Upvotes: 13

Related Questions