Overriding default Jinja dictionary attributes in Python view templates

Jan 29th, 2017 in  by Michael Cho

How to use the `do` Jinja extension to modify an existing dictionary in your view template.

In my Flask application, I use a default dictionary with values for the site's meta tags, which are passed to most view templates.

It looks something like this:

# in a 'controller'-type file
@app.route('/', methods=['GET'])
def index():
    meta = {
        'title': 'Top secret Python shortcuts',
        'description': 'An introduction to Python.',
        'keywords': 'Flask, Python, Jinja'
    return render_template('index.html', meta=meta)

# in a Jinja view template
<title> {{ meta['title'] }}<title/>
<meta name="description" content="{{ meta['description'] }}" >
<meta name="keywords" content="{{ meta['keywords'] }}" >

However on many pages I want to override these defaults with something more specific for that particular page.

If I had used simple Jinja variables instead of a dictionary, this could be easily accomplished with set, ie

# in a Jinja template
{% set meta_title="Diving into Jinja" %}
<title> {{ meta_title }}<title/>

Alas since I want to use a dictionary, the solution is not so simple. We must use the `do` Jinja extension to modify the dictionary attributes instead.

# shortly after initialising the Flask app

# in a Jinja template
{% do meta.update({'title':'Diving into Jinja'}) %}
<title> {{ meta['title'] }}<title/>

And that, is how you modify a dictionary in a Jinja template.