Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a list from Python, by Jinja2 to JavaScript

Let's say I have a Python variable:

list_of_items = ['1','2','3','4','5'] 

and I pass it to Jinja by rendering HTML, and I also have a function in JavaScript called somefunction(variable). I am trying to pass each item of list_of_items. I tried something like this:

{% for item in list_of_items %} <span onclick="somefunction({{item}})">{{item}}</span><br> {% endfor %} 

Is it possible to pass a list from Python to JavaScript or should I pass each item from list one by one in a loop? How can I do this?

like image 536
user1843766 Avatar asked Mar 10 '13 10:03

user1843766


People also ask

Can Jinja2 be used with JavaScript?

Jinja is one of the most used template engines for Python. This project is a JavaScript implementation with emphasis on simplicity and performance, compiling templates into readable JavaScript that minifies well.

How do you pass a list from JavaScript to Python?

To pass some context data to javascript code, you have to serialize it in a way it will be "understood" by javascript (namely JSON). You also need to mark it as safe using the safe Jinja filter, to prevent your data from being htmlescaped.

Is Jinja2 a Python?

Jinja is a template engine for Python. It is similar to the Django template engine.


2 Answers

To pass some context data to javascript code, you have to serialize it in a way it will be "understood" by javascript (namely JSON). You also need to mark it as safe using the safe Jinja filter, to prevent your data from being htmlescaped.

You can achieve this by doing something like that:

The view

import json  @app.route('/') def my_view():     data = [1, 'foo']     return render_template('index.html', data=json.dumps(data)) 

The template

<script type="text/javascript">     function test_func(data) {         console.log(data);     }     test_func({{ data|safe }}) </script> 

Edit - exact answer

So, to achieve exactly what you want (loop over a list of items, and pass them to a javascript function), you'd need to serialize every item in your list separately. Your code would then look like this:

The view

import json  @app.route('/') def my_view():     data = [1, "foo"]     return render_template('index.html', data=map(json.dumps, data)) 

The template

{% for item in data %}     <span onclick=someFunction({{ item|safe }});>{{ item }}</span> {% endfor %} 

Edit 2

In my example, I use Flask, I don't know what framework you're using, but you got the idea, you just have to make it fit the framework you use.

Edit 3 (Security warning)

NEVER EVER DO THIS WITH USER-SUPPLIED DATA, ONLY DO THIS WITH TRUSTED DATA!

Otherwise, you would expose your application to XSS vulnerabilities!

like image 153
mdeous Avatar answered Sep 29 '22 09:09

mdeous


I had a similar problem using Flask, but I did not have to resort to JSON. I just passed a list letters = ['a','b','c'] with render_template('show_entries.html', letters=letters), and set

var letters = {{ letters|safe }} 

in my javascript code. Jinja2 replaced {{ letters }} with ['a','b','c'], which javascript interpreted as an array of strings.

like image 21
Godsmith Avatar answered Sep 29 '22 09:09

Godsmith