5

How do I get a list of all the arguments passed to a Jinja2 template?

If I have an extremely generic template and I want to list all the arguments passed (for debug reasons) is there a way to do it?

Something like:

mytemplate.html

{% for argument in LIST_OF_ARGUMENT %}
    {{ argument }}<br>
{% endfor %}

so in the view /foobar

if I call the template in this way:

return render_template('mytemplate.html', form=myform, foo='bar')

I get

the_content_of_form <br>
bar <br>

while if I call the template in this way:

return render_template('mytemplate.html', lorem=ipsum, fooooo='barrrrr')

I get

the_content_of_lorem <br>
barrrrr <br>
Giovanni Di Milia
  • 13,480
  • 13
  • 55
  • 67

2 Answers2

2

Well you just need to pass them as an argument to render_template, probably the most common use of this involves passing a list of dictionaries as an argument to render template:

def Viewfunction():
     #do something, get something from db as result and then
     arguments = [dict(name=row[0],age=row[1]) for row in result.fetchall()]

     return render_template('mytemplate.html', form=myform, arguments=arguments)

and then access them like so:

 {% for item in arguments %}
   {{ item.name }}
   {{ item.age }}
 {% endfor %}

Obviously you can also pass all other lists, not just lists of dictionaries to the template, you loop over them in a very similar way.

As for debugging I have found Flask built in debugging tools very useful, if you get an exception you just get a page where you can execute code, if you're interested in all your variables there you can simply type locals() into one of the frames within stacktrace. You just need to enable debug mode to make use of it, just remember to turn it off in production.

Here's a working example for you, it's taken from flaskr sample app included in flask when you download it under examples folder:

@app.route('/')
def show_entries():
    db = get_db()
    cur = db.execute('select title, text from entries order by id desc')
    entries = cur.fetchall()
    return render_template('show_entries.html', entries=entries,local=locals())

When you do:

{% for item in local %}
{{ item }}
{% endfor %}

you'll get db cur entries, is this what you want?

Pawel Miech
  • 7,742
  • 4
  • 36
  • 57
  • Thanks for the answer, but I see this more like a workaround and not like a real answer to the question. – Giovanni Di Milia Aug 05 '13 at 18:17
  • What exactly you need? It's actually an interesting question. I've edited my answer slightly. – Pawel Miech Aug 05 '13 at 18:38
  • what I need is a generic way to access all the parameters passed to the template and make some checks on them. The problem is that I want to do this in a "layout" template that is extended by the actual templates used in the different views, so I don't have any clue which kind of variables (objects instances, simple strings or other) that have been passed nor the possible names. I hope it gave you an idea of the problem. – Giovanni Di Milia Aug 05 '13 at 19:03
  • Aha! So you need something like a debugging template, there is something like this here: https://pypi.python.org/pypi/Flask-DebugToolbar – Pawel Miech Aug 05 '13 at 19:17
  • well, something like that, but then I need to do something more than see the variables. But I like the way they extract only the variables and exclude template filters and other stuff from the context. I'll look how they do in their code! Thanks! – Giovanni Di Milia Aug 05 '13 at 19:29
0

Take a look at the jinja2.runtime.Context

"The template context holds the variables of a template. It stores the values passed to the template and also the names the template exports"

"The template context supports read only dict operations (get, keys, values, items, iterkeys, itervalues, iteritems, getitem, contains). Additionally there is a resolve() method that doesn’t fail with a KeyError but returns an Undefined object for missing variables."

codegeek
  • 32,236
  • 12
  • 63
  • 63