Multi-Page Apps and URL Support
Multi-Page Apps and URL Support
https://github.com/AnnMarieW/dash-multi-page-app-demos
/dash-bootstrap-components: example (collapsible-sidebar-with-icons)
Dash는 single-page app으로 web applications을 랜더링한다.
dcc.Link를  사용할때는  Application이 완전히 reload되지 않는다.
따라서, navigating할때,이것은 브라우징을 매우 빠르게 만듭니다. 
 
Dash에서 multi-page apps을 구축하기 위해서는 
URL 라우팅에 필요한 callback 로직를 추상화하고, 
Callback과 함께 dcc.Location 및 dcc.Link와 같은 구성 요소를 사용하여, Datash Page를 쉽게 만들수 있다. 
여기서 만약 Dash page를 사용하지 않고 다중 페이지 앱을 구축하려는 경우 다른 옵션을 사용할 수 있습니다.
Dash Pages
Dash 2.5 버전부터, Dash Pages는 multi-page app을 쉽게 만들수 있도록
URL 라우팅 처리를 담당하고,
앱 내 페이지를 구조화하고 정의하는 간단한 방법을 제공한다.
print(dash.__version__) # 현재버전 확인 > ver 2.5
$ pip list --outdated $ pip list | grep das 전체 팩키지 업그레이드 $ pip install dash --upgrade $ pip install dash-bootstrap-components --upgrade $ conda upgrade --all $ pip freeze | grep -v "^-e" | cut -d = -f 1 | xargs -n 1 pip install -U # Dash만 $ pip install dash --upgrade $ pip install dash-bootstrap-components --upgrade
Multi-page App을 생성하는 기본 단계
- /pages 디렉토리에 각 페이지를 위한 개별 .py 파일을 만듭니다.
- 각 페이지 파일에서:
- dash.register_page(name)을 추가 ==> 이것이 앱의 페이지임을 Dash에게 알립니다.
- 레이아웃 또는 레이아웃을 반환하는 함수인 layout 내에서 페이지 내용을 정의합니다.
- 메인 앱 파일인 app.py에서:
- 앱을 선언할 때 use_pages를 True로 설정합니다: app = Dash(name, use_pages=True)
- 사용자가 앱의 페이지 경로 중 하나를 방문할 때 페이지 내용이 표시되는 위치에 dash.page_container를 추가합니다.

Query Strings , Variable Paths(path_template)
get함수나 path를 통해 변수의 값을 전달.
multi_page_cache_background_callback
import dash
import dash_bootstrap_components as dbc
from dash import Input, Output, dcc, html
PLOTLY_LOGO = "https://images.plot.ly/logo/new-branding/plotly-logomark.png"
app = dash.Dash(
    __name__,
    external_stylesheets=[
        dbc.themes.BOOTSTRAP,
        dbc.icons.FONT_AWESOME
    ]
)
sidebar = html.Div(className="sidebar", children=[
    html.Div(className="sidebar-header", children=[
        html.Img(src=PLOTLY_LOGO, style={"width": "3rem"}),
        html.H2("Sidebar"),
    ]),
    html.Hr(),
    dbc.Nav(vertical=True, pills=True, children=[
        dbc.NavLink(href="/", active="exact", children=[
            html.I(className="fas fa-home me-2"), html.Span("Home")
        ]),
        dbc.NavLink(href="/calendar", active="exact", children=[
            html.I(className="fas fa-calendar-alt me-2"),
            html.Span("Calendar"),
        ]),
        dbc.NavLink(href="/calendar", active="exact", children=[
            html.I(className="fas fa-envelope-open-text me-2"),
            html.Span("Messages"),
        ]),
    ]),
])
content = html.Div(
    id="page-content", className="content"
)
app.layout = html.Div([dcc.Location(id="url"), sidebar, content])
# set the content according to the current pathname
@app.callback(Output("page-content", "children"), Input("url", "pathname"))
def render_page_content(pathname):
    if pathname == "/":
        return html.P("This is the home page!")
    elif pathname == "/calendar":
        return html.P("This is your calendar... not much in the diary...")
    elif pathname == "/messages":
        return html.P("Here are all your messages")
    # If the user tries to reach a different page, return a 404 message
    return html.Div(className="p-3 bg-light rounded-3", children=[
        html.H1("404: Not found", className="text-danger"),
        html.Hr(),
        html.P(f"The pathname {pathname} was not recognised..."),
    ])
if __name__ == "__main__":
    app.run_server(debug=True, port=8881)