¿Cómo generar una lista delimitada por comas en la plantilla jinja python?

179

Si tengo una lista de userspalabras ["Sam", "Bob", "Joe"], quiero hacer algo donde pueda generar mi archivo de plantilla jinja:

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

Quiero hacer que la plantilla de salida sea:

Sam, Bob, Joe

Intenté el código anterior para verificar si estaba en la última iteración del bucle y, si no, no inserte una coma, pero no funciona. ¿Cómo hago esto?

Rolando
fuente
jinja, como Python, no se usa !como operador de negación. "no" se deletrea "no".
Wooble

Respuestas:

306

Desea que su ifcheque sea:

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

Tenga en cuenta que también puede acortar el código utilizando If Expression :

{{ "," if not loop.last }}
Joe Day
fuente
2
Esto es increíble, especialmente al final del ciclo en html
Sinux
77
Solo para tu información, es posible que necesites hacer esto un if / else basado en tu configuración. Más información. se puede encontrar aquí: github.com/pallets/jinja/issues/710
Paul Calabro
1
o es algunos casos{{ "," if not forloop.last }}
obotezat
55
Secundo el comentario sobre agregar otro. Esto funcionó para mí{{ "," if not loop.last else "" }}
ahong
197

también puede usar el filtro incorporado "join" ( http://jinja.pocoo.org/docs/templates/#join así:

{{ users|join(', ') }}
Uli Martens
fuente
1
Si bien esto funciona para crear un csv, al ver su ejemplo anterior, no se puede usar con el ancla circundante.
triunenature
Este enfoque tampoco funciona bien con el escape: ['{{[' a \ '', 'b'] | join ("','")}} '] produce [' a & # 39; & # 39; , & # 39; b ']
stewbasic
66
Esto debería ser lo primero que se intenta. Si no funciona como se desea, intente con otra solución, pero esta es definitivamente la más limpia.
Jerad
Esto da una coma final, ¿cómo me deshago de eso?
Jonathan
Probablemente tenga un elemento vacío final. Si tienes tres elementos abc, obtendrás aXbXc cuando te unas a X:ansible -i localhost, all -m debug -a "msg=\"{{ [ 'a','b','c' ]|join('X') }}\""
Uli Martens
61

Y usando el joinerde http://jinja.pocoo.org/docs/dev/templates/#joiner

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

Está hecho para este propósito exacto. Normalmente, una combinación o una comprobación de forloop.last sería suficiente para una sola lista, pero para múltiples grupos de cosas es útil.

Un ejemplo más complejo de por qué lo usarías.

{% 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 %}
dalore
fuente
1
Esto realmente funcionó bastante bien para mí, sin dejar una coma final. Gracias por este!
Daniel Andrei Mincă
7

El siguiente código funcionó usando el filtro de unión jinja2 que Uli Martens sugirió en el shell python3.5:

>>> users = ["Sam", "Bob", "Joe"]
>>> from jinja2 import Template
>>> template = Template("{{ users|join(', ') }}")
>>> template.render(users=users)
'Sam, Bob, Joe'
rok
fuente