288

If I have a list of users say ["Sam", "Bob", "Joe"], I want to do something where I can output in my jinja template file:

{% for user in userlist %}
    <a href="/profile/{{ user }}/">{{ user }}</a>
    {% if !loop.last %}
        , 
    {% endif %}
{% endfor %}   

I want to make the output template be:

Sam, Bob, Joe

I tried the above code to check if it was on the last iteration of the loop and if not, then don't insert a comma, but it does not work. How do I do this?

1
  • 2
    jinja, like Python, does not use ! as a negation operator. "not" is spelled "not". Commented Aug 15, 2012 at 17:49

3 Answers 3

479

You want your if check to be:

{% if not loop.last %}
    ,
{% endif %}

Note that you can also shorten the code by using If Expression:

{{ ", " if not loop.last else "" }}
Sign up to request clarification or add additional context in comments.

5 Comments

Just fyi, you might need to make this an if/else based on your settings. More info. can be found here: github.com/pallets/jinja/issues/710
or is some cases {{ "," if not forloop.last }}
I second the comment about adding an else. This worked for me {{ "," if not loop.last else "" }}
In my case it was forloop instead of loop and {% instead of {{, like this: {% if not forloop.last %},{% endif %}. Other solutions did not work
or even shorter: {{ "" if loop.last else ", " }}
306

You could also use the builtin join filter like this:

{{ users|join(', ') }}

7 Comments

While this works for creating a csv, seeing his example above, it can't be used with the surrounding anchor.
This approach also doesn't work well with escaping: ['{{ ['a\'', 'b']|join("', '") }}'] produces ['a&#39;&#39;, &#39;b']
This should be the first thing attempted. If it doesn't work as desired, then try another solution, but this is definitely cleanest.
This gives a trailing comma, how do I get rid of that?
You probably have an trailing empty element. If you've got three elements a b c you will get aXbXc when joining with X: ansible -i localhost, all -m debug -a "msg=\"{{ [ 'a','b','c' ]|join('X') }}\""
|
87

And using the joiner from https://jinja.palletsprojects.com/templates/#joiner

{% set comma = joiner(",") %}
{% for user in userlist %}
    {{ comma() }}<a href="/profile/{{ user }}/">{{ user }}</a>
{% endfor %}  

It's made for this exact purpose. Normally a join or a check of forloop.last would suffice for a single list, but for multiple groups of things it's useful.

A more complex example on why you would use it.

{% set pipe = joiner("|") %}
{% if categories %} {{ pipe() }}
    Categories: {{ categories|join(", ") }}
{% endif %}
{% if author %} {{ pipe() }}
    Author: {{ author() }}
{% endif %}
{% if can_edit %} {{ pipe() }}
    <a href="?action=edit">Edit</a>
{% endif %}

1 Comment

This actually worked pretty well for me, without leaving a trailing comma. Thanks for this one!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.