{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "(dash-pages)=\n", "# Dash Pages\n", "\n", "Dash Pages 从 Dash 版本 2.5.0 开始提供。它实现了简化创建多页面应用的功能,处理 URL 路由,并提供了一种简单的方法来组织和定义应用中的页面。\n", "\n", "使用 Dash Pages 创建多页面应用有三个基本步骤:\n", "\n", "1. 为您应用中的每个页面创建单独的 `.py` 文件,并将它们放在 `/pages` 目录中。\n", "2. 在这些页面文件中需要:\n", " - 添加 `dash.register_page(__name__)`,告诉 Dash 这是应用中的页面。\n", " - 在名为 `layout` 的变量中或名为 `layout` 的函数中定义页面的内容,该函数返回内容。\n", "3. 在您的主应用文件,`app.py` 中:\n", " - 在声明您的应用时,将 `use_pages` 设置为 `True`:`app = Dash(__name__, use_pages=True)`\n", " - 在您想要在用户访问应用的某个页面路径时显示页面内容的地方,添加 `dash.page_container` 到您的应用布局中。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 示例:使用 Pages 的简单多页面应用\n", "\n", "下面是使用 Dash Pages 的三页面应用结构的样子:\n", "\n", "```\n", "- app.py\n", "- pages\n", " |-- analytics.py\n", " |-- home.py\n", " |-- archive.py\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "它有主 `app.py` 文件,这是我们多页面应用的入口点(我们在其中包含 `dash.page_container`),并且在 `pages` 目录中有三页。\n", "\n", ":::::{tab-set}\n", "::::{tab-item} pages/analytics.py\n", "```{include} pages/analytics.py\n", ":code: python\n", "```\n", "::::\n", "::::{tab-item} pages/home.py\n", "```{include} pages/home.py\n", ":code: python\n", "```\n", "::::\n", "::::{tab-item} pages/archive.py\n", "```{include} pages/archive.py\n", ":code: python\n", "```\n", "::::\n", "::::{tab-item} app.py\n", "```{include} app.py\n", ":code: python\n", "```\n", "::::\n", ":::::" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images/sample_pages_app_1.gif)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "- `path` — 我们在应用的三个页面中的每一个上调用 `dash.register_page`。对于其中两个页面,我们没有设置 `path` 属性。如果您不设置 `path` 属性,它将根据模块名称自动生成。因此,当用户访问 `/archives` 时,会提供 `archives.py` 的布局。同样,当用户访问 `/analytics` 时,会提供 `analytics.py` 的布局。当我们为 `home.py` 调用 `dash.register_page` 时,我们确实设置了 `path` 属性。对于 `home.py`,我们设置 `path` 属性是因为我们不希望在用户访问 `/home` 时显示内容,而是在用户访问主页:`/` 时显示。\n", "- `page_registry` — 包含对 `dash.register_page` 的调用的页面会被添加到我们应用的页面注册表中。这是一个我们可以从中提取有关应用页面信息的 `OrderedDict`。在我们的 `app.py` 中,我们遍历应用的所有页面(在 `dash.page_registry.values()` 中)并为每一个添加链接。我们也可以从 `dash.page_registry` 中单独选择这些链接。路径为 `/` 的页面总是在字典中的索引 `0`。其他页面按字母顺序排列。\n", "- `page_container` — `app.py` 中有 `dash.page_container`。当用户导航到该页面的路径时,此处会显示页面内容。\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## layout" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在上面的示例中,我们在每个页面中使用名为 `layout` 的变量定义布局。例如,在上面的 `home.py` 中:\n", "\n", "```python\n", "layout = html.Div([\n", " html.H1('This is our Home page'),\n", " html.Div('This is our Home page content.'),\n", "])\n", "```\n", "\n", "您也可以使用名为 `layout` 的函数来返回页面内容:\n", "\n", "```python\n", "def layout():\n", " return html.Div([\n", " html.H1('This is our Home page'),\n", " html.Div('This is our Home page content.'),\n", " ])\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "页面布局必须使用名为 `layout` 的变量或函数来定义。在创建带有 Pages 的应用时,只在主 `app.py` 文件中使用 `app.layout`。\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `dash.register_page`\n", "\n", "在文件中调用 [`dash.register_page`](https://dash.plotly.com/urls#reference-for-dash.register_page) 是 Dash 知道将该文件作为多页面应用中的页面包含的方式。\n", "\n", "正如我们所见,它可以仅使用模块名称进行调用:\n", "\n", "```python\n", "dash.register_page(__name__)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在这种情况下,Dash 会根据模块名称生成页面的路径、标题和链接名称。\n", "\n", "```{note}\n", "标题是 HTML 的 `