Reputation: 1166
If I return a Jinja2 template like so:
return render_response('home.htm', **context)
How do then get a list of the variables in context from within the template?
Upvotes: 32
Views: 29907
Reputation: 329
Jinja2 now has an extension that will give you debug information. Example using Flask:
import flask
app = flask.Flask(__name__)
app.jinja_env.add_extension('jinja2.ext.debug')
@app.route('/')
def hello():
return flask.render_template('hello.html')
DEBUG = True # Or from your environment settings
if DEBUG:
print("Running in DEBUG mode.")
@app.context_processor
def commonContext():
context = {"DEBUG":DEBUG} # And any other variables you always want every template to be able to see
return context
if __name__ == '__main__':
app.run(debug=DEBUG)
At the bottom of your hello.html (or in your base template):
{% if DEBUG %}
<section>
<h3>Debug Info</h3>
<pre>{% debug %}</pre>
</section>
{% endif %}
Upvotes: 0
Reputation: 17353
I found @Garrett's answer to be a bit more complex than what I wanted. I found that I can easily inspect the context by adding a clone of the context to the context itself:
contextCopy = dict(context)
context['all'] = contextCopy
And then pretty printing that into my Jinja template with <pre>{{ all|pprint }}</pre>
.
Upvotes: 3
Reputation: 49768
Technically, because context is not passed as a named dictionary, a little work is required to generate a list of the context variables from inside a template. It is possible though.
Define a Jinja context function to return the jinja2.Context object, which is essentially a dictionary of the global variables/functions
Make that function available in the global namespace; i.e. a jinja2.Environment or jinja2.Template globals dictionary
Optionally, filter objects from the context; for instance, use callable()
to skip Jinja's default global helper functions (range, joiner, etc.). This may be done in the context function or the template; wherever it makes the most sense.
Example:
>>> import jinja2
>>>
>>> @jinja2.contextfunction
... def get_context(c):
... return c
...
>>> tmpl = """
... {% for key, value in context().items() %}
... {% if not callable(value) %}
... {{ key }}:{{ value }}
... {% endif %}
... {% endfor %}
... """
>>>
>>> template = jinja2.Template(tmpl)
>>> template.globals['context'] = get_context
>>> template.globals['callable'] = callable
>>>
>>> context = {'a': 1, 'b': 2, 'c': 3}
>>>
>>> print(template.render(**context))
a:1
c:3
b:2
[Alternately, call render_response
with ('home.htm', context=context)
to make the other solution work.]
Upvotes: 39
Reputation: 20556
Here's how to get @crewbum's answer working from a Flask app:
import jinja2
@jinja2.contextfunction
def get_context(c):
return c
app.jinja_env.globals['context'] = get_context
app.jinja_env.globals['callable'] = callable
Upvotes: 4