Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

zip(list1, list2) in Jinja2?

I'm doing code generation in Jinja2 and I frequently want to iterate through two lists together (i.e. variables names and types), is there a simple way to do this or do I need to just pass a pre-zipped list? I was unable to find such a function in the docs or googling.

like image 449
John Salvatier Avatar asked Mar 06 '11 02:03

John Salvatier


People also ask

How do you write a for loop in Jinja2?

Jinja2 being a templating language has no need for wide choice of loop types so we only get for loop. For loops start with {% for my_item in my_collection %} and end with {% endfor %} . This is very similar to how you'd loop over an iterable in Python.

Which 3 features are included in the Jinja2 templates?

Some of the features of Jinja are: sandboxed execution. automatic HTML escaping to prevent cross-site scripting (XSS) attacks. template inheritance.

What is Autoescape in Jinja2?

When autoescaping is enabled, Jinja2 will filter input strings to escape any HTML content submitted via template variables. Without escaping HTML input the application becomes vulnerable to Cross Site Scripting (XSS) attacks. Unfortunately, autoescaping is False by default.


3 Answers

Modify the jinja2.Environment global namespace itself if you see fit.

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

This may be helpful in separating view (template) logic from application logic, but it enables the reverse as well. #separationofconcerns

like image 194
Garrett Avatar answered Oct 24 '22 05:10

Garrett


Since you didn't mention if you are using Flask or not I figured I'd add my findings.

To be used by a render_template() create the 'zip' filter using the zip() function in the Jinja2 environment used by Flask.

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

To use this within a template do it like this:

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

Keep in mind that strings are iterable Jinja2 so if you try to zip to strings you'll get some crazy stuff. To make sure what you want to zip is iterable and not a string do this:

{%  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 %}
like image 27
TheZeke Avatar answered Oct 24 '22 06:10

TheZeke


For Flask, you can pass the zip in the render_template()

  return render_template("home.html", zip=zip)
like image 7
Mantej Singh Avatar answered Oct 24 '22 07:10

Mantej Singh