diff --git a/CHANGELOG.md b/CHANGELOG.md index d1bd5edff0..5480eb2d53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## Added +- [#2826](https://github.com/plotly/dash/pull/2826) When using Pages, allows for `app.title` and (new) `app.description` to be used as defaults for the page title and description. Fixes [#2811](https://github.com/plotly/dash/issues/2811). - [#2795](https://github.com/plotly/dash/pull/2795) Allow list of components to be passed as layout. -- [2760](https://github.com/plotly/dash/pull/2760) New additions to dcc.Loading resolving multiple issues: +- [#2760](https://github.com/plotly/dash/pull/2760) New additions to dcc.Loading resolving multiple issues: - `delay_show` and `delay_hide` props to prevent flickering during brief loading periods (similar to Dash Bootstrap Components dbc.Spinner) - `overlay_style` for styling the loading overlay, such as setting visibility and opacity for children - `target_components` specifies components/props triggering the loading spinner diff --git a/dash/_pages.py b/dash/_pages.py index c204dfdc18..ab97ba80df 100644 --- a/dash/_pages.py +++ b/dash/_pages.py @@ -235,13 +235,14 @@ def register_page( order `0` - `title`: - (string or function) The name of the page . That is, what appears in the browser title. - If not supplied, will use the supplied `name` or will be inferred by module, - e.g. `pages.weekly_analytics` to `Weekly analytics` + (string or function) Specifies the page title displayed in the browser tab. + If not supplied, the app's title is used if different from the default "Dash". + Otherwise, the title is the given `name` or inferred from the module name. + For example, `pages.weekly_analytics` is inferred as "Weekly Analytics". - `description`: (string or function) The <meta type="description"></meta>. - If not supplied, then nothing is supplied. + If not defined, the application description will be used if available. - `image`: The meta description image used by social media platforms. @@ -319,10 +320,18 @@ def register_page( ) page.update( supplied_title=title, - title=(title if title is not None else page["name"]), + title=title + if title is not None + else CONFIG.title + if CONFIG.title != "Dash" + else page["name"], ) page.update( - description=description if description else "", + description=description + if description + else CONFIG.description + if CONFIG.description + else "", order=order, supplied_order=order, supplied_layout=layout, diff --git a/dash/dash.py b/dash/dash.py index 1876eecd15..985fb01c4f 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -366,6 +366,9 @@ class Dash: functions. The syntax for this parameter is a dict of State objects: `routing_callback_inputs={"language": Input("language", "value")}` NOTE: the keys "pathname_" and "search_" are reserved for internal use. + + :param description: Sets a default description for meta tags on Dash pages (use_pages=True). + """ _plotlyjs_url: str @@ -404,6 +407,7 @@ def __init__( # pylint: disable=too-many-statements add_log_handler=True, hooks: Union[RendererHooks, None] = None, routing_callback_inputs: Optional[Dict[str, Union[Input, State]]] = None, + description=None, **obsolete, ): _validate.check_obsolete(obsolete) @@ -458,6 +462,7 @@ def __init__( # pylint: disable=too-many-statements title=title, update_title=update_title, include_pages_meta=include_pages_meta, + description=description, ) self.config.set_read_only( [ diff --git a/tests/integration/multi_page/test_pages_layout.py b/tests/integration/multi_page/test_pages_layout.py index 355ec50d40..fe11c1d5b5 100644 --- a/tests/integration/multi_page/test_pages_layout.py +++ b/tests/integration/multi_page/test_pages_layout.py @@ -235,3 +235,27 @@ def test_pala005_routing_inputs(dash_duo, clear_pages_state): # Changing the language Input re-runs the layout function dash_duo.select_dcc_dropdown("#language", "fr") dash_duo.wait_for_text_to_equal("#contents", "Le hash dit: #123") + + +def get_app_title_description(): + app = Dash( + __name__, use_pages=True, title="App Title", description="App Description" + ) + dash.register_page("home", layout=html.Div("Home"), path="/") + dash.register_page( + "page1", + layout=html.Div("Page1"), + title="Page 1 Title", + description="Page 1 Description", + ) + app.layout = html.Div(dash.page_container) + return app + + +def test_pala006_app_title_discription(dash_duo, clear_pages_state): + dash_duo.start_server(get_app_title_description()) + + assert dash.page_registry["home"]["title"] == "App Title" + assert dash.page_registry["page1"]["title"] == "Page 1 Title" + assert dash.page_registry["home"]["description"] == "App Description" + assert dash.page_registry["page1"]["description"] == "Page 1 Description"