✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🧬 Learn how to build RNA-Seq data apps with Python & Dash. Register for the May 20 Webinar!

Include layout inside another layout

Hi,
Is it possible to ‘nest’ layouts?
I have a ten page dashboard app.
Some of the pages would have the same filter controls for the charts on the page.

I was wondering if I could group those controls into a ‘panel’ and have it in a separate file that I could include in the layout for a page.

I am using the dcc.location with code like this to move between pages…

dash_app.layout = html.Div(style={'font-family': '"Dosis",sans-serif'},children=[
        dcc.Location(id='url', refresh=False),
       dbc.Row( # Main Body of the page
            [
                dbc.Col(html.Div(id='page-content')),
            ]
        ),
  ...

And then the callback loads the layout which has been included from another file using import.


@dash_app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/wave1' :
        return page3layout
    elif pathname == '/wave2':
         return page3layout
    elif pathname == '/wave3':
         return wave3layout
    elif pathname == '/report1':
         return layout_report1
etc
etc

So I’m looking for maybe ‘include’ functionality? Or some way to make a control group that can be included in layouts as needed… so that I can have a filter_panel.py and import that into the page layout…

Otherwise I will have to copy and paste the filter panel 10 or more times…

Thanks

OK,
I’ve actually worked out a way to do it.
Using callbacks…

Actually I better explain the nesting…
So I have the main dash_app layout that always loads… then in that I have a div called page-content that gets populated by the main callback…

dash_app.layout = html.Div(style={'font-family': '"Dosis",sans-serif'},children=[
        dcc.Location(id='url', refresh=False),
       dbc.Row( # Main Body of the page
            [
                dbc.Col(html.Div(id='page-content')),
            ]
        ),
  ...

I get the page-content from the first callback…and the imported layouts…

from home_layout import layout_home
from report3_layout import layout_report3
from about_layout import about_layout

@dash_app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/' :
        return layout_home
    elif pathname == '/wave2':
         return page3layout
    elif pathname == '/wave3':
         return wave3layout
    elif pathname == '/report1':
         return layout_report1
etc
etc

And in, say the layout_home… I have another placeholder… this time for the filters…

home_layout = html.Div([
       
        dbc.Row(
            [
                dbc.Col( dbc.Card([dcc.Loading(id="loading-1", children=[dcc.Graph(id='govt_recs', className="pretty_container", )], type="default")
                ])),
                dbc.Col(id='filtercontrols', width=4),
            ]
        ),
etc
etc

and then back in the main file I have added a second callback to deal with populating the filtercontrols placeholder…

@dash_app.callback(Output('filtercontrols', 'children'),
              [Input('url', 'pathname')])
def show_filters(pathname):
    return filterlayout

Ahhnndd… unlike a lot of things I do… this actually works!!