2011-03-06 18 views
17

Estoy generando código en Jinja2 y con frecuencia quiero iterar a través de dos listas (es decir, nombres y tipos de variables), ¿hay alguna manera simple de hacerlo o solo tengo que pasar una lista preincronizada? No pude encontrar dicha función en el docs o en Google.zip (list1, list2) en Jinja2?

Respuesta

26

Modificar el jinja2.Environment global namespace sí si lo considera oportuno.

import jinja2 
env = jinja2.Environment() 
env.globals.update(zip=zip) 
# use env to load template(s) 

Esto puede ser útil para separar la lógica de vista (plantilla) de la lógica de la aplicación, pero también permite lo contrario. # separationofconcerns

2

No creo que los lenguajes de creación de plantillas permitan hacer el zip de dos contenedores durante el ciclo. Aquí hay una pregunta similar para django y la plantilla de jinja está muy cerca de django.

Debería preconstruir el contenedor comprimido y pasarlo a su plantilla.

>> for i,j in zip(range(10),range(20,30)): 
...  print i,j 
... 

es equivalente a

>>> [(i,j) for i,j in zip(range(10),range(20,30))] 
+0

OK, lo sospechaba mucho. FWIW, resolví esto al combinar mis listas en una sola lista de una nueva clase, que de todos modos es más elegante. –

1

Como no mencionaste si estás usando Flask o no, pensé que agregaría mis hallazgos.

Para ser utilizado por un render_template() cree el filtro 'zip' utilizando la función zip() en el entorno Jinja2 utilizado por Flask.

app = Flask(__name__) 
... 
app.jinja_env.filters['zip'] = zip 

Para utilizar esta dentro de una plantilla de hacerlo de esta manera:

{% for value1, value2 in iterable1|zip(iterable2) %} 
    {{ value1 }} is paired with {{ value2 }} 
{% endfor %} 

Tenga en cuenta que las cadenas son iterables Jinja2 por lo que si se intenta comprimir en cadenas obtendrá algunas cosas locas. Para asegurarse de que lo que desea comprimir es iterable y no una cadena, haga esto:

{% if iterable1 is iterable and iterable1 is not string 
    and iterable2 is iterable and iterable2 is not string %} 
    {% for value1, value2 in iterable1|zip(iterable2) %} 
     {{ value1 }} is paired with {{ value2 }} 
    {% endfor %} 
{% else %} 
    {{ iterable1 }} is paired with {{ iterable2 }} 
{% endif %}