Reputation: 3894
Based on the first part of the path an app is accessed from, I want the app to render differently. I tried setting a variable on the request
using middleware and then accessing it in the template. I printed some debug information, which did show up so I know the middleware code ran, but the value wasn't set once I got to the template. How can I set a variable inside middleware that can be used in Flask?
from werkzeug.wrappers import Request
class NavMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
request = Request(environ)
print('path: %s, url: %s' % (request.path, request.url))
if request.path.startswith("/myapp"):
print("Here")
request.application = "Myapp"
environ['application'] = "Myapp"
return self.app(environ, start_response)
{% if request.application == "Myapp" %}
{% include 'navbar_myapp.html' %}
{% endif %}
Upvotes: 5
Views: 2409
Reputation: 127190
The request
object you created in the middleware has no relation to the request
object that Flask builds. Only the environ
is passed between WSGI layers. The correct way for middleware to modify the request that subsequent layers see is to modify the environ
dict. You've done that, so you need to access the value in request.environ
, not on the request
object itself.
class NavMiddleware:
def __init__(self, app, app_name):
self.app = app
self.app_name = app_name
def __call__(self, environ, start_response):
request = Request(environ)
first_path = request.path.lstrip("/").partition("/")[0]
environ["nav_middleware.app_name"] = first_path
return self.app(environ, start_response)
app = Flask(__name__)
app.wsgi_app = NavMiddleware(app.wsgi_app, "my_app")
{% if request.environ["nav_middleware.app_name"] == "my_app" %}
This answer applies to middleware in general, but in this particular case there's no need for middleware. WSGI servers can mount applications at different SCRIPT_NAME
locations, which is exposed as request.script_root
. You can simulate this in dev with Werkzeug's DispatcherMiddleware
.
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(app, {"/one": app, "/two": app})
{% if request.script_root == "/one" %}
Upvotes: 5