Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jinja2 and Flask: Pass variable into parent template without passing it into children

Let's say I have a base template with a header in it, and the content of that header needs to be passed into the template.

<header>
  You are logged in as {{ name }}
</header>

This base template gets extended by many pages. How can I pass in that variable without passing it to each individual child? For example, I don't want to have to do this:

render_template("child1.html", name=user.name)
render_template("child2.html", name=user.name)
render_template("child3.html", name=user.name)
etc...

because who knows how many child pages I might have. It doesn't feel DRY enough.

I never actually render the base template, only its children, but I don't know how else to pass in data.

Is there a way to do this? Should I not be using inheritance?

like image 490
robert.vinluan Avatar asked Jul 23 '13 19:07

robert.vinluan


2 Answers

May I suggest you use the global variable 'g' in flask. This is by default available in the jinja templates. So you don't need to worry about passing it anywhere in the base template or children. Just make sure you set it first when you login

g.username = user.name

then in templates, just do this:

You are logged in as {{ g.username }}
like image 177
codegeek Avatar answered Oct 14 '22 14:10

codegeek


You need to use Flask's context-processors:

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

See this similar SO question and answer.

An example of how I am using it (to simply insert app config settings):

@app.context_processor
def lib_versions():
    return dict(
        bokehversion = app.config['BOKEH_VERSION'],
        jqueryversion = app.config['JQUERY_VERSION'],
        jqueryuiversion = app.config['JQUERYUI_VERSION'],
        bootstrapversion = app.config['BOOTSTRAP_VERSION'],
    )

Which are pulled from my Flask config file:

class Config(object):
    DEBUG = True
    TESTING = True
    SQLALCHEMY_DATABASE_URI = ''
    TMP_DIR = ''
    STATIC_FOLDER = ''
    BOKEH_VERSION = '0.8.2'
    JQUERY_VERSION = '1.11.2'
    JQUERYUI_VERSION = '1.11.4'
    BOOTSTRAP_VERSION = '3.3.4'

class ProductionConfig(Config):
    DEBUG = False
    TESTING = False

You then call these in your base template just like any other Jinja2 variable:

<!-- START: CSS -->
<link rel="stylesheet" media="screen" type="text/css" href="http://cdn.bokeh.org/bokeh/release/bokeh-{{ bokehversion }}.min.css">
<!-- END: CSS -->
<!-- START: JS -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/{{ jqueryversion }}/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/{{ jqueryuiversion }}/jquery-ui.min.js"></script>
<script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/{{ bootstrapversion }}/js/bootstrap.min.js"></script>
<!-- END: JS -->
like image 45
tatlar Avatar answered Oct 14 '22 13:10

tatlar