Reputation: 111
I create a context_process in blueprint apple,
apple > views.py
@apple.context_processor
def eat_apple():
return dict(fruit='apple')
If i were in another blueprint, how would i access @apple.context_processor, so that I can use the variable when i render a template?
Upvotes: 3
Views: 4147
Reputation: 47
Since I cannot reply to posts yet: I also was a bit struggling with this. My first solution worked but had some nasty side-effects with gunicorn.
What worked when using flask run
, but what definitely will NOT WORK when using gunicorn
or similar which is using multiple workers and your application is using ORM eg. sqlalchemy:
In my create_app()
I added the following lines (after blueprints got registered)
app.app_context().push()
from appserver.utils import context_processors
Although this works with gunicorn
, I got weird behavior with database-mutations. Only mutation that were done in a specific worker would show up on the front-end, but when you navigate away and back the that page it might be entirely possible the page is served by a different worker. I do not exactly know how this works - apparently the session is tied to a worker and so "sees" only those changes.
What does work:
The changes I had the make (thanks for the hint @user885983) were quite easy now:
In create_app()
in replaced the lines above with the following and moved them where the other blueprints are being registered:
from appserver.utils import bp as utils_bp
app.register_blueprint(utils_bp)
and replaced @bp.context_processor
with @bp.app_context_processor
I use this technique to load variables I need in all (jinja) templates like so (where backend is Class I created that handles a lot of common funtions:
@bp.app_context_processor
def get_menu_icons():
menu_icon = backend.get_menu_icons()
return dict(menu_icon=menu_icon)
This way I don't have to apply the variable to render_template()
and still use it in the template: {{ menu_icon.delete }}
eg.
Upvotes: 0
Reputation: 508
You can use Bluepint.app_context_processor
e.g.
bp = Blueprint("myblueprint", __name__, url_prefix=None)
@myblueprint.app_context_processor
def inject_template_globals():
company = Company.query.first()
return dict(company=company)
Upvotes: 10
Reputation: 13120
Instead of assigning it to the blueprint, assign it to the app.
@app.context_processor
def eat_apple():
return dict(fruit='apple')
The whole point of having a blueprint-local context processor is that it only operates on that blueprint. So if that's not what you want, put it on the app.
Upvotes: 7