How to create a global variable for render_template()?

Viewed 119

I have a simple task: to pass the same variable for different routes in the render_template() function. This value is in the base template and I need to pass it on every render_template() function. Can I set this value as a global so that I don't have to set it in every function for different routes?

@app.route('/hello')
def hello(name=None):
    return render_template('hello.html', value=value)

@app.route('/bye')
def bye(name=None):
    return render_template('bye.html', value=value)
3 Answers

To make variables available to templates without having to burden your routes with passing those variables, use Flask context processors. See https://flask.palletsprojects.com/en/2.1.x/templating/#context-processors for details an an example.

Here's one that I use to 'cache bust' CSS so that browsers won't accidentally use stale versions.

style_css_path = os.path.join(os.path.dirname(__file__), 'static', 'style.css')
style_css_mtime = int(os.stat(style_css_path).st_mtime)

@app.context_processor
def cache_busters():
    return {
        'style_css_mtime': style_css_mtime,
    }

The base template can then do

<link rel="stylesheet"
      href="{{ url_for('static', filename='style.css') }}?v={{ style_css_mtime }}" />

Any template that uses base.html inherits this behavior without routes that use that template having to pass style_css_time.

You could use a partial from functools like this:

from functools import partial

# Define a function that takes 2 parameters
def someFunc(a,b):
   print(f'Called with a:{a} and b:{b}')

# Define a "partial" where the parameters are partially pre-filled in
p1 = partial(someFunc, b="I was added for free")

# Now call the already partially defined function "p1"
p1("Hello")

Result

Called with a:Hello and b:I was added for free

I found the correct solution to my question in the Flask documentation:

Context Processors To inject new variables automatically into the context of a template, context processors exist in Flask. Context processors run before the template is rendered and have the ability to inject new values into the template context. A context processor is a function that returns a dictionary. The keys and values of this dictionary are then merged with the template context, for all templates in the app:

@app.context_processor
def inject_user():
    return dict(user=g.user)

The context processor above makes a variable called user available in the template with the value of g.user. This example is not very interesting because g is available in templates anyways, but it gives an idea how this works.

Related