Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I send variables to Jinja template from a Flask decorator?

Many routes around my blueprinted flask app will need to send 'sidebar data' to jinja.

I'm looking for the most efficient way to do this. Their has to be something better than importing my 'generate_sidebar_data()' function into every blueprint, repeatedly saying:

var1, var2, var3 = generate_sidebar_data() 

and then sending them with 'render_template':

return render_template('template.html',                            var1=var1,                            var2=var2,                            var3=var3                       ) 

What I want is a decorator that I can put with the route that will do the same thing the above does (run function and send the vars to jinja) but I don't know if this is possible. How do you send variables to jinja from inside a decorator function?

@blueprint.route('/') @include_sidebar_data def frontpage():      return render_template('template.html') 
like image 384
chrickso Avatar asked Apr 07 '13 04:04

chrickso


People also ask

How do you declare a variable in Jinja template?

{{ }} tells the template to print the value, this won't work in expressions like you're trying to do. Instead, use the {% set %} template tag and then assign the value the same way you would in normal python code. It was great explanation and simple one.


2 Answers

I'm going to propose something even simpler than using a decorator or template method or anything like that:

def render_sidebar_template(tmpl_name, **kwargs):     (var1, var2, var3) = generate_sidebar_data()     return render_template(tmpl_name, var1=var1, var2=var2, var3=var3, **kwargs) 

Yup, just a function. That's all you really need, isn't it? See this Flask Snippet for inspiration. It's essentially doing exactly the same sort of thing, in a different context.

like image 167
wheaties Avatar answered Oct 07 '22 22:10

wheaties


You can use a context processor (http://flask.pocoo.org/docs/api/#flask.Flask.context_processor):

def include_sidebar_data(fn):     @blueprint.context_processor     def additional_context():         # this code work if endpoint equals to view function name         if request.endpoint != fn.__name__:             return {}          var1, var2, var3 = generate_sidebar_data()         return {             'var1': var1,             'var2': var2,             'var3': var3,         }     return fn   @blueprint.route('/') @include_sidebar_data def frontpage():     return render_template('template.html') 

UPD: I like the next example more and it is better if the decorator is used for several view functions:

sidebar_data_views = []   def include_sidebar_data(fn):     sidebar_data_views.append(fn.__name__)     return fn   @blueprint.context_processor def additional_context():     # this code work if endpoint equals to view function name     if request.endpoint not in sidebar_data_views:         return {}      var1, var2, var3 = generate_sidebar_data()     return {         'var1': var1,         'var2': var2,         'var3': var3,     }   @blueprint.route('/') @include_sidebar_data def frontpage():     return render_template('template.html') 
like image 35
tbicr Avatar answered Oct 07 '22 23:10

tbicr