I have spent some time playing around with different multi-page approaches. I thought I would share this one as it seems useful to other people.
Firstly this is just an extension of https://dash.plot.ly/urls and doesn’t provide any completely new functionality. But sometimes you want to directly load the layout without waiting for some multi-page callback to kick in, here are examples of doing that:
For those times try this approach based on the Referer URL:
# Standard Libary
from urllib.parse import urlparse
# Third Party Libraries
import dash
import flask
import dash_html_components as html
def serve_layouts(layout_dict):
def serve_layouts_closure():
if not flask.has_request_context():
return html.Div()
referer = flask.request.headers.get('Referer', '')
path = urlparse(referer).path
pages = path.split('/')
if len(pages) < 2 or not pages[1]:
return html.Div('Root Page')
page = pages[1]
if page in layout_dict:
return layout_dict[page]
return html.Div('Nothing here but us chickens')
return serve_layouts_closure
server = flask.Flask(__name__)
app = dash.Dash(__name__, server=server)
app.config.supress_callback_exceptions = True
page_one_layout = html.Div('Hello World')
page_two_layout = html.Div('Hello World!!', style={'font-weight': 'bold'})
secret_layout = html.Div('Ssshhhh, this is a secret easter egg')
app.layout = serve_layouts({'page1': page_one_layout,
'page2': page_two_layout,
'secret': secret_layout})
if __name__ == '__main__':
app.run_server()
With this script try visiting:
- http://127.0.0.1:8050
- http://127.0.0.1:8050/page1
- http://127.0.0.1:8050/page2
- http://127.0.0.1:8050/secret
- http://127.0.0.1:8050/foo
Now instead of parsing out the page from the Referer URL we could also parse out a query string and produce a custom page based on that query string (this is something I do quite often).
Here’s how you would get started:
# Standard Libary
from urllib.parse import urlparse, parse_qs
# Third Party Libraries
import dash
import flask
import dash_html_components as html
def serve_layout():
if not flask.has_request_context():
return html.Div()
query = ''
referer = flask.request.headers.get('Referer')
if referer:
query_string = urlparse(referer).query
if query_string:
query = parse_qs(query_string)
return html.Div(f'Your query was: {query}')
server = flask.Flask(__name__)
app = dash.Dash(__name__, server=server)
app.config.supress_callback_exceptions = True
app.layout = serve_layout
if __name__ == '__main__':
app.run_server()
With this example try going to http://127.0.0.1:8050/?page=custom&option=foo
Again all of this can be achieved with callbacks and dcc.Link
, but with this approaches the custom page is served at layout time. Hope it helps someone!