Search code examples
javascriptpythonvariablesjinja2

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?


Solution


  • This answer is unsafe, please refer to Mark Amery's answer below for the right way to do this.


    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!