Skip to content

Commit dfc29a5

Browse files
committed
added support for nested folders in /pages
1 parent 5cbe864 commit dfc29a5

File tree

6 files changed

+133
-3
lines changed

6 files changed

+133
-3
lines changed

dash_labs/plugins/pages.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from dash import callback, Output, Input, html, dcc
22
import dash
33
import os
4+
import glob
45
import importlib
56
from collections import OrderedDict
67
import json
@@ -223,18 +224,20 @@ def _filename_to_name(filename):
223224

224225

225226
def _filename_to_path(filename):
226-
return "/" + filename.split(".")[-1].replace("_", "-").lower()
227+
return filename.replace("_", "-").replace(".", "/").lower().split("pages")[-1]
227228

228229

229230
def plug(app):
230231
# Import the pages so that the user doesn't have to.
231232
# TODO - Do validate_layout in here too
232233
dash.page_registry = OrderedDict()
233234

234-
for page_filename in os.listdir("pages"):
235+
for page_filename in glob.iglob("pages/**", recursive=True):
236+
_, _, page_filename = page_filename.partition("pages/")
235237
if page_filename.startswith("_") or not page_filename.endswith(".py"):
236238
continue
237239
page_filename = page_filename.replace(".py", "")
240+
page_filename = page_filename.replace("/", ".")
238241
page_module = importlib.import_module(f"pages.{page_filename}")
239242

240243
if f"pages.{page_filename}" in dash.page_registry:
@@ -253,7 +256,6 @@ def router():
253256
def update(pathname, search):
254257
path_id = app.strip_relative_path(pathname)
255258
query_parameters = _parse_query_string(search)
256-
257259
layout = None
258260
for module in dash.page_registry:
259261
page = dash.page_registry[module]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import dash
2+
import dash_labs as dl
3+
import dash_bootstrap_components as dbc
4+
5+
6+
app = dash.Dash(
7+
__name__, plugins=[dl.plugins.pages], external_stylesheets=[dbc.themes.BOOTSTRAP]
8+
)
9+
10+
navbar = dbc.NavbarSimple(
11+
dbc.DropdownMenu(
12+
[
13+
dbc.DropdownMenuItem(page["name"], href=page["path"])
14+
for page in dash.page_registry.values()
15+
if page["module"] != "pages.not_found_404"
16+
],
17+
nav=True,
18+
label="More Pages",
19+
),
20+
brand="Multi Page App Plugin Demo",
21+
color="primary",
22+
dark=True,
23+
className="mb-2",
24+
)
25+
26+
app.layout = dbc.Container(
27+
[navbar, dl.plugins.page_container],
28+
fluid=True,
29+
)
30+
31+
if __name__ == "__main__":
32+
app.run_server(debug=True)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import dash
2+
3+
dash.register_page(__name__)
4+
5+
print(__name__)
6+
7+
from dash import Dash, dcc, html, Input, Output, callback
8+
import plotly.express as px
9+
10+
df = px.data.tips()
11+
days = df.day.unique()
12+
13+
layout = html.Div(
14+
[
15+
dcc.Dropdown(
16+
id="dropdown",
17+
options=[{"label": x, "value": x} for x in days],
18+
value=days[0],
19+
clearable=False,
20+
),
21+
dcc.Graph(id="bar-chart"),
22+
]
23+
)
24+
25+
26+
@callback(Output("bar-chart", "figure"), Input("dropdown", "value"))
27+
def update_bar_chart(day):
28+
mask = df["day"] == day
29+
fig = px.bar(df[mask], x="sex", y="total_bill", color="smoker", barmode="group")
30+
return fig
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
import dash
3+
dash.register_page(__name__, path="/")
4+
print(__name__)
5+
6+
from dash import Dash, dcc, html, Input, Output, callback
7+
import plotly.express as px
8+
9+
df = px.data.medals_wide(indexed=True)
10+
11+
layout = html.Div(
12+
[
13+
html.P("Medals included:"),
14+
dcc.Checklist(
15+
id="heatmaps-medals",
16+
options=[{"label": x, "value": x} for x in df.columns],
17+
value=df.columns.tolist(),
18+
),
19+
dcc.Graph(id="heatmaps-graph"),
20+
]
21+
)
22+
23+
24+
@callback(Output("heatmaps-graph", "figure"), Input("heatmaps-medals", "value"))
25+
def filter_heatmap(cols):
26+
fig = px.imshow(df[cols])
27+
return fig
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import dash
2+
3+
dash.register_page(__name__)
4+
5+
from dash import Dash, dcc, html, Input, Output, callback
6+
import plotly.express as px
7+
import numpy as np
8+
9+
np.random.seed(2020)
10+
11+
layout = html.Div(
12+
[
13+
dcc.Graph(id="histograms-graph"),
14+
html.P("Mean:"),
15+
dcc.Slider(
16+
id="histograms-mean", min=-3, max=3, value=0, marks={-3: "-3", 3: "3"}
17+
),
18+
html.P("Standard Deviation:"),
19+
dcc.Slider(id="histograms-std", min=1, max=3, value=1, marks={1: "1", 3: "3"}),
20+
]
21+
)
22+
23+
24+
@callback(
25+
Output("histograms-graph", "figure"),
26+
Input("histograms-mean", "value"),
27+
Input("histograms-std", "value"),
28+
)
29+
def display_color(mean, std):
30+
data = np.random.normal(mean, std, size=500)
31+
fig = px.histogram(data, nbins=30, range_x=[-10, 10])
32+
return fig
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from dash import html
2+
import dash
3+
4+
dash.register_page(__name__, path="/404")
5+
6+
7+
layout = html.H1("Custom 404")

0 commit comments

Comments
 (0)