I am using https://dash.plotly.com/urls and https://dash.plotly.com/urls#reference-for-dash.register_page as my references to create a Multi-Page app. I have Variable Paths working properly with all of my layouts in a /pages folder, but I would like to have everything in a single file. When I do so, I cannot figure out how get the URL argument passed to the layout function.
The documentation states: path_template
: Add variables to a URL by marking sections with <variable_name>. The layout function then receives the <variable_name> as a keyword argument. e.g. path_template= “/asset/<asset_id>” then if pathname in browser is “/assets/a100” then layout will receive **{“asset_id”:“a100”}
but that doesn’t seem to be working when I define my own layout function as is necessary when using a single file. In the example below, kwargs is always null, even when a report path is set in the URL:
here is my code:
from dash import Dash, html, dcc, callback, Input, Output
import dash
def layout_analytics():
return html.Div([
html.H1('This is our Analytics page'),
html.Div([
"Select a city: ",
dcc.RadioItems(
options=['New York City', 'Montreal', 'San Francisco'],
value='Montreal',
id='analytics-input'
)
]),
html.Br(),
html.Div(id='analytics-output'),
])
def layout_archive():
return html.Div([
html.H1('This is our Archive page'),
html.Div('This is our Archive page content.')
])
def layout_home_page():
return html.Div([
html.H1('This is our Home page'),
html.Div('This is our Home page content.'),
])
def layout_report(**kwargs):
return html.Div([
html.H1('This is our Reports page'),
html.Div(f'Requested report: ? kwargs={kwargs}'),
])
app = Dash(__name__, use_pages=True, pages_folder="")
dash.register_page("home", path='/', layout=layout_home_page())
dash.register_page("analytics", layout=layout_analytics())
dash.register_page("archive", layout=layout_archive())
dash.register_page("report", path_template="/report/<report_id>",
layout=layout_report())
app.layout = html.Div([
html.Div([
html.Div(
dcc.Link(f"{page['name']} - {page['path']}", href=page["relative_path"])
) for page in dash.page_registry.values()
]),
dash.page_container,
])
@callback(
Output('analytics-output', 'children'),
Input('analytics-input', 'value')
)
def update_city_selected(input_value):
return f'You selected: {input_value}'
if __name__ == '__main__':
app.run(debug=True)
My layouts are quite complex and already defined within an OO structure so this is just an example to see whether I can plug everything in correctly or not. I have things working with URL parameters in a fishy way, but I really would prefer the pages working in this manner.