Skip to content

Commit 7550a59

Browse files
committed
added documentation and example for nested folders in /pages
updates from first review black
1 parent dfc29a5 commit 7550a59

23 files changed

+356
-72
lines changed

CHANGELOG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ Unlike other Plotly projects, `dash-labs` does **not** adhere to semantic versio
55

66
### Added
77
- Added Dash Pages: A plug-in to simplify building multi-page apps.
8-
- Added documentation: 08-DashPages.
9-
- Added demos: 4 examples of multi-page apps using the Dash Pages plug-in.
8+
- Added documentation: 08-MultiPageDashApp.md and 09-MultiPageDashAppExamples.md.
9+
- Added demos: examples of multi-page apps using the Dash Pages plug-in.
1010

1111
### Removed
1212
- removed code, tests, and demos for projects documented in chapter 02 through 07.

README.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,18 @@ The documentation for Dash Labs can be found in the [docs/](./docs/) directory.
1515

1616
_New in dash-labs v1.0.0:_
1717
- [08-MultiPageDashApp.md](https://github.com/plotly/dash-labs/blob/main/docs/08-MultiPageDashApp.md)
18-
18+
- [09-MultiPageDashAppExamples.md](https://github.com/plotly/dash-labs/blob/main/docs/09-MultiPageDashAppExamples.md)
19+
1920
Examples and demos are located in the [docs/demos](./docs/demos) directory.
2021

2122
## Installation
22-
To install the tech preview:
23+
To install the latest version of dash-labs:
2324

2425
```
2526
$ pip install -U dash-labs
2627
```
28+
29+
To install the archived version:
30+
```
31+
$ pip install dash-labs==0.4.0
32+
```

dash_labs/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.0.0"
1+
__version__ = "1.0.0rc1"

docs/01-Overview.md

+38-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,53 @@
11
# Overview
2-
Dash Labs is a project that will be used to explore future enhancements to Dash. The goal is that the successful ideas from this project will migrate into future versions of Dash itself. And over time, new ideas will be added to this library.
2+
Dash Labs is a project that we use to explore future enhancements to Dash. The goal is that the successful ideas from this project will migrate into future versions of Dash itself. And over time, new ideas will be added to this library.
3+
4+
We encourage you to join the discussion, raise issues, make pull requests, and take an active role in shaping the funture of Dash.
35

46
## Initial Design Goals
57
Dash Labs began with several interdependent design goals:
68
- Provide a more concise syntax for generating simple Dash apps that follow a variety of nice looking predefined templates.
79
- Make it possible for third-party developers to make and distribute custom templates.
810
- Ensure that there is a smooth continuum between concision, and the flexibility of "full Dash". A concise syntax should not be a dead-end, requiring the developer to rewrite the app in order to reach a certain level of sophistication.
9-
- Improve ability of users to encapsulate and reuse custom interactive component workflows, and make it possible for third-party developers to distribute these as plugins.
11+
- Improve ability of users to encapsulate and reuse custom interactive component workflows, and make it possible for third-party developers to distribute these as plugins.
12+
13+
You will find the result of these initial goals archived in dash-labs v0.4.0. Many of the featured developed here made their way into Dash 2.0 and Dash 2.1.
14+
15+
### Dash Labs 1.0.0 Goals
16+
17+
Dash Labs 1.0.0 is reset to start with Dash >= 2.0 as the base. We will continually add new projects, the first of which is
18+
the new and imporoved way to make multi-page apps.
19+
20+
21+
## Documentation
22+
The documentation for Dash Labs can be found in the [docs/](./docs/) directory.
23+
- [01-Overview.md](https://github.com/plotly/dash-labs/blob/main/docs/01-Overview.md)
24+
25+
_Archived in dash-labs v0.4.0:_
26+
- [02-CallbackEnhancements.md](https://github.com/plotly/dash-labs/blob/main/docs/02-CallbackEnhancements.md)
27+
- [03-TemplateLayoutSystem.md](https://github.com/plotly/dash-labs/blob/main/docs/03-TemplateLayoutSystem.md)
28+
- [04-PredefinedTemplates.md](https://github.com/plotly/dash-labs/blob/main/docs/04-PredefinedTemplates.md)
29+
- [05-ComponentPlugingPattern.md](https://github.com/plotly/dash-labs/blob/main/docs/05-ComponentPlugingPattern.md)
30+
- [06-TemplateIntegrationAndMigration.md](https://github.com/plotly/dash-labs/blob/main/docs/06-TemplateIntegrationAndMigration.md)
31+
- [07-LongCallback.md](https://github.com/plotly/dash-labs/blob/main/docs/07-LongCallback.md)
32+
33+
_New in dash-labs v1.0.0:_
34+
- [08-MultiPageDashApp.md](https://github.com/plotly/dash-labs/blob/main/docs/08-MultiPageDashApp.md)
35+
- [09-MultiPageDashAppExamples.md](https://github.com/plotly/dash-labs/blob/main/docs/09-MultiPageDashAppExamples.md)
1036

11-
# Installation
12-
Dash Labs can be installed using `pip` with
37+
Examples and demos are located in the [docs/demos](./docs/demos) directory.
38+
39+
## Installation
40+
To install the latest version of dash-labs:
1341

1442
```
1543
$ pip install -U dash-labs
1644
```
1745

46+
To install the archived version:
47+
```
48+
$ pip install dash-labs==0.4.0
49+
```
50+
1851
To use the demos based on `dash-bootstrap-components`:
1952

2053
```
@@ -28,7 +61,7 @@ The Dash Labs functionality is enabled by specifying an instance of `dash_labs.P
2861
from dash import Dash
2962
import dash_labs as dl
3063

31-
app = Dash(__name__, plugins=[dl.plugins.pages_plugin()])
64+
app = Dash(__name__, plugins=[dl.plugins.pages])
3265
```
3366

3467
> Note: it is recommended to import `dash_labs` as `dl`, and this is the convention that will be used throughout this document.

docs/02-CallbackEnhancements.md

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
- ----------------------------------------------------------------------------------
99
- This documentation describes code in a previous version of dash-labs (v0.4.0)
1010
- and is included here for legacy purposes only.
11+
-
12+
- You can install v0.4.0 with:
13+
- pip install dash-labs==0.4.0
14+
1115
- ----------------------------------------------------------------------------------
1216
```
1317

docs/03-TemplateLayoutSystem.md

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
- ----------------------------------------------------------------------------------
1414
- This documentation describes code in a previous version of dash-labs (v0.4.0)
1515
- and is included here for legacy purposes only.
16+
-
17+
- You can install v0.4.0 with:
18+
- pip install dash-labs==0.4.0
1619
- ----------------------------------------------------------------------------------
1720
```
1821

docs/04-PredefinedTemplates.md

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
- ----------------------------------------------------------------------------------
1414
- This documentation describes code in a previous version of dash-labs (v0.4.0)
1515
- and is included here for legacy purposes only.
16+
-
17+
- You can install v0.4.0 with:
18+
- pip install dash-labs==0.4.0
1619
- ----------------------------------------------------------------------------------
1720
```
1821

docs/05-ComponentPlugingPattern.md

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
- ----------------------------------------------------------------------------------
99
- This documentation describes code in a previous version of dash-labs (v0.4.0)
1010
- and is included here for legacy purposes only.
11+
-
12+
- You can install v0.4.0 with:
13+
- pip install dash-labs==0.4.0
1114
- ----------------------------------------------------------------------------------
1215
```
1316

docs/06-TemplateIntegrationAndMigration.md

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
- ----------------------------------------------------------------------------------
1414
- This documentation describes code in a previous version of dash-labs (v0.4.0)
1515
- and is included here for legacy purposes only.
16+
-
17+
- You can install v0.4.0 with:
18+
- pip install dash-labs==0.4.0
1619
- ----------------------------------------------------------------------------------
1720
```
1821

docs/07-LongCallback.md

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
- ----------------------------------------------------------------------------------
99
- This documentation describes code in a previous version of dash-labs (v0.4.0)
1010
- and is included here for legacy purposes only.
11+
-
12+
- You can install v0.4.0 with:
13+
- pip install dash-labs==0.4.0
1114
- ----------------------------------------------------------------------------------
1215
```
1316

docs/08-MultPageDashApp.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ if __name__ == "__main__":
8282
- Define `layout`. This can be a variable or function that returns a component
8383
- Call `dash.register_page(__name__)` to tell `dl.plugins.pages` that this page should be part of the multi-page framework
8484

85-
For example, here is the first page of our app
86-
link
85+
For example, here is the first page of our app:
86+
8787
```python
8888
import dash
8989
dash.register_page(__name__, path="/")
@@ -114,7 +114,7 @@ def filter_heatmap(cols):
114114

115115
The `dash.page_registry` is an `OrderedDict` with keys being the page's module name (e.g. `pages.bar-charts`) and values being a dictionary containing keys `path`, `name`, `order`, `title`, `description`, `image`, and `layout`.
116116
As you saw in the above example, This `page_registry` is populated from calling `dash.register_page` within `pages/`.
117-
`dash.register_page` will can accept various arguments to customize aspects about the page. See the Advanced Features section below.
117+
`dash.register_page` will accept various arguments to customize aspects about the page. See the Advanced Features section below.
118118

119119

120120
![multi_page](https://user-images.githubusercontent.com/72614349/140232399-efe7020d-480a-40af-a0b0-40e66dcd9d56.gif)

docs/09-MultPageDashAppExamples.md

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
2+
> ## Status: Multi-Page Dash App Plugin
3+
> #### Under active development: A plugin to simplify creating multi-page Dash apps. This is a preview of functionality that will be added to Dash 2.1.
4+
> **[See the community announcement for details and discussion](https://community.plotly.com/t/introducing-dash-pages-dash-2-1-feature-preview/57775/2)**
5+
6+
7+
8+
# Multi-Page Dash App Plugin Examples
9+
10+
**Please see Chapter 08-MultiPageDashApp for an introduction to the Multi-Page Dash App Plugin**
11+
12+
If you would like to add an example, feel free to create a pull request! For more information, see the documentation issue #xx.
13+
14+
### Example: Nested Folders
15+
This example shows how `dash.register_page` handles
16+
- Using Nested folders in `pages/`
17+
- Storing icons as arbitrary keyword arguments
18+
19+
See the code in `/demos/multi-page-nested-folders`
20+
21+
In larger multi-page apps it's common to organize topics into categories. Each category may have it's own folder with multiple
22+
pages. This plugin automatically searches all subdirectories in `pages/` and includes all the apps.
23+
In our example the `heatmaps.py` is in `pages/` and `pie-chart.py` is in `pages/chapter/`.
24+
The `dash.page_registry` dictionary will include the subdirectory name(s) in the dict key and the module and path like this:
25+
```python
26+
OrderedDict([
27+
('pages.heatmaps', {
28+
'module': 'pages.heatmap',
29+
'path': '/heatmap',
30+
...
31+
}
32+
),
33+
('pages.chapter.pie-chart', {
34+
'module': 'pages.chapter.pie-chart',
35+
'path': '/chapter/pie-chart',
36+
...
37+
}
38+
),
39+
...
40+
])
41+
```
42+
43+
In this example app, we will create a sidebar nav for the app pages located in the `chapter/` folder. We use a `dbc.Offcanvas()` component and open the sidebar nav with a button.
44+
45+
Here is the `app.py`
46+
47+
```python
48+
import dash
49+
from dash import dcc, html, Output, Input, State
50+
import dash_labs as dl
51+
import dash_bootstrap_components as dbc
52+
53+
54+
app = dash.Dash(
55+
__name__,
56+
plugins=[dl.plugins.pages],
57+
external_stylesheets=[dbc.themes.BOOTSTRAP, dbc.icons.FONT_AWESOME],
58+
)
59+
60+
61+
navbar = dbc.NavbarSimple(
62+
dbc.DropdownMenu(
63+
[
64+
dbc.DropdownMenuItem(page["name"], href=page["path"])
65+
for page in dash.page_registry.values()
66+
if not page["path"].startswith("/chapter")
67+
],
68+
nav=True,
69+
label="More Pages",
70+
),
71+
brand="Multi Page App Plugin Demo",
72+
color="primary",
73+
dark=True,
74+
className="mb-2",
75+
)
76+
77+
sidebar_button = dbc.Button(html.I(className="fa fa-bars"), id="sidebar-btn")
78+
sidebar = dbc.Offcanvas(
79+
dbc.Nav(
80+
[html.H3("Chapters")]
81+
+ [
82+
dbc.NavLink(
83+
[
84+
html.I(className=page["icon"]),
85+
html.Span(page["name"], className="ms-2"),
86+
],
87+
href=page["path"],
88+
active="exact",
89+
)
90+
for page in dash.page_registry.values()
91+
if page["path"].startswith("/chapter")
92+
],
93+
vertical=True,
94+
pills=True,
95+
),
96+
id="offcanvas",
97+
)
98+
99+
app.layout = dbc.Container(
100+
[
101+
navbar,
102+
dbc.Row(
103+
[
104+
dbc.Col([sidebar_button], width=1),
105+
dbc.Col([sidebar, dl.plugins.page_container]),
106+
]
107+
),
108+
],
109+
fluid=True,
110+
)
111+
112+
113+
@app.callback(
114+
Output("offcanvas", "is_open"),
115+
Input("sidebar-btn", "n_clicks"),
116+
State("offcanvas", "is_open"),
117+
)
118+
def toggle_theme_offcanvas(n1, is_open):
119+
if n1:
120+
return not is_open
121+
return is_open
122+
123+
124+
if __name__ == "__main__":
125+
app.run_server(debug=True)
126+
127+
```
128+
129+
Recall from the previous chapter that `dash.register_page` also accepts arbitrary keyword arguments. We use this
130+
feature to store the icon used in the nav for each page.
131+
132+
Here is how we store the FontAwesome icon for `pages/chapter/pie-chart.py`
133+
134+
```python
135+
136+
dash.register_page(__name__, icon="fas fa-chart-pie")
137+
```
138+
139+
You can see how the icon is included in the sidebar navigation:
140+
141+
![nested_folders](https://user-images.githubusercontent.com/72614349/140660047-d97e80b0-72dd-4fbe-b862-55f5a6431331.gif)

docs/demos/multi-page-basics/app.py

+26-26
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,29 @@
55
app = Dash(__name__, plugins=[dl.plugins.pages])
66

77

8-
dash.register_page('another_page', layout='Another page', path='/another-page')
9-
dash.register_page('and_again', layout='And again!', path='/and-again')
10-
11-
12-
app.layout = html.Div([
13-
html.H1('App Frame'),
14-
15-
html.Div(
16-
dcc.Link('Go back home', href=dash.page_registry['pages.home']['path'])
17-
),
18-
19-
html.Div([
20-
html.Div(dcc.Link(
21-
f"{page['name']} - {page['path']}",
22-
href=page['path']
23-
))
24-
for page in dash.page_registry.values()
25-
if page['module'] != 'pages.not_found_404'
26-
]),
27-
dl.plugins.page_container
28-
])
29-
30-
31-
if __name__ == '__main__':
32-
app.run_server(debug=True)
33-
8+
dash.register_page("another_page", layout="Another page", path="/another-page")
9+
dash.register_page("and_again", layout="And again!", path="/and-again")
10+
11+
12+
app.layout = html.Div(
13+
[
14+
html.H1("App Frame"),
15+
html.Div(
16+
dcc.Link("Go back home", href=dash.page_registry["pages.home"]["path"])
17+
),
18+
html.Div(
19+
[
20+
html.Div(
21+
dcc.Link(f"{page['name']} - {page['path']}", href=page["path"])
22+
)
23+
for page in dash.page_registry.values()
24+
if page["module"] != "pages.not_found_404"
25+
]
26+
),
27+
dl.plugins.page_container,
28+
]
29+
)
30+
31+
32+
if __name__ == "__main__":
33+
app.run_server(debug=True)

0 commit comments

Comments
 (0)