{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "The `SlidesTemplate` is a simple extension of the basic template that uses the [reveal.js](https://revealjs.com/) presentation framework to present the published outputs as a set of slides. It is a list-like variant where the `main` area acts like a list-like container but unlike other list-like templates the individual items are published as separate slides (unless marked as a fragment).\n", "\n", "## Basic Templates\n", "\n", "For a large variety of use cases we do not need complete control over the exact layout of each individual component on the page, as could be achieved with a [custom template](../../user_guide/Templates.ipynb), we just want to achieve a more polished look and feel. For these cases Panel ships with a number of default templates, which are defined by declaring four main content areas on the page, which can be populated as desired:\n", "\n", "* **`header`**: The header area of the HTML page\n", "* **`sidebar`**: A collapsible sidebar\n", "* **`main`**: The main area of the application\n", "* **`modal`**: A modal area which can be opened and closed from Python\n", "\n", "These four areas behave very similarly to other Panel layout components and have list-like semantics. This means we can easily append new components into these areas. Unlike other layout components however, the contents of the areas is fixed once rendered. If you need a dynamic layout you should therefore insert a regular Panel layout component (e.g. a `Column` or `Row`) and modify it in place once added to one of the content areas. \n", "\n", "Templates can allow for us to quickly and easily create web apps for displaying our data. Panel comes with a default Template, and includes multiple Templates that extend the default which add some customization for a better display.\n", "\n", "#### Parameters:\n", "\n", "In addition to the four different areas we can populate the default templates also provide a few additional parameters:\n", "\n", "* **`busy_indicator`** (BooleanIndicator): Visual indicator of application busy state.\n", "* **`collapsed_sidebar`** (str, `default=True`): Whether the sidebar (if present) is initially collapsed.\n", "* **`header_background`** (str): Optional header background color override.\n", "* **`header_color`** (str): Optional header text color override.\n", "* **`logo`** (str): URI of logo to add to the header (if local file, logo is base64 encoded as URI).\n", "* **`site`** (str): Name of the site. Will be shown in the header. Default is '', i.e. not shown.\n", "* **`site_url`** (str): Url of the site and logo. Default is \"/\".\n", "* **`title`** (str): A title to show in the header.\n", "* **`theme`** (Theme): A Theme class (available in `panel.template.theme`)\n", "* **`sidebar_width`** (int): The width of the sidebar in pixels. Default is 330.\n", "\n", "##### reveal.js parameters\n", "\n", "The `SlideTemplate` which is based on reveal.js additionally has some additional:\n", "\n", "* **`reveal_config`** (`dict`): The reveal.js [config](https://revealjs.com/config/) options to apply\n", "* **`reveal_theme`** (str): The reveal.js theme to apply (one of `black | white | league | beige | night | solarized | simple`)\n", "* **`show_header`** (bool, `default=False`): Toggles the header on and off. Since slides rarely need a header the default is False and title and logo are rendered at the bottom of the slides.\n", "\n", "________" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this case we are using the `SlidesTemplate`, built on top of reveal.js. It differs slightly to other templates so we will start by setting up the code and then go through the template configuration step-by-step." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "import hvplot.pandas\n", "import numpy as np\n", "import panel as pn\n", "import pandas as pd\n", "\n", "pn.extension(design=pn.theme.Material)\n", "\n", "xs = np.linspace(0, np.pi)\n", "\n", "freq = pn.widgets.FloatSlider(name=\"Frequency\", start=0, end=10, value=2)\n", "phase = pn.widgets.FloatSlider(name=\"Phase\", start=0, end=np.pi)\n", "\n", "widgets = pn.WidgetBox(freq, phase, horizontal=True)\n", "\n", "def sine(freq, phase):\n", " return pd.DataFrame(dict(y=np.sin(xs*freq+phase)), index=xs)\n", "\n", "def cosine(freq, phase):\n", " return pd.DataFrame(dict(y=np.cos(xs*freq+phase)), index=xs)\n", "\n", "dfi_sine = hvplot.bind(sine, freq, phase).interactive()\n", "dfi_cosine = hvplot.bind(cosine, freq, phase).interactive()\n", "\n", "plot_opts = dict(responsive=True, min_height=400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By default the `SlidesTemplate` will not render a header and instead render the title and logo at the bottom of the template. If you do want a header you can enable it with `show_header=True`. Additionally, unlike other templates, if added, the `sidebar` is hidden by default." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "template = pn.template.SlidesTemplate(\n", " title='The slide title', logo='https://raw.githubusercontent.com/holoviz/panel/main/doc/_static/logo_stacked.png'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When adding to the template each new root added to the main area will add a new slide. However, if you want to add multiple fragments to the same slide (revealed as you advance slides) then you can add a `tags=['fragment']` to a component:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "template.main.extend([ \n", " pn.pane.Markdown('Slides Template', styles={'font-size': '3em'}, align='center'),\n", " pn.Card(dfi_sine.hvplot(**plot_opts).output(), widgets, title='Sine', margin=20, tags=['fragment']),\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will add two slides to our template: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "template.main.append(\n", " pn.Card(dfi_cosine.hvplot(**plot_opts).output(), widgets, title='Cosine', margin=20),\n", ")\n", "\n", "template.servable();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Each built-in template comes with a *light* (default) and *dark* theme. The theme can be set when instantiating the template with the `theme` parameter, or [globally](../../how_to/styling/themes.md). Unless set explicitly it can also be toggled by adding `?theme=dark` or `?theme=default` to the URL.\n", "\n", "

SlidesTemplate with DefaultTheme

\n", "\n", "
\n", "

SlidesTemplate with DarkTheme

\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ":::{tip}\n", "Built-in templates don't render necessarily well in a notebook as their styling can badly interact with the notebook built-in styling. You can disable rendering the output of a cell using `;`, as done above. For development purposes, the app can be quickly rendered in another tab by replacing `.servable()` with `.show()`. Alternatively, the [JupyterLab Preview](../../how_to/notebook/jupyterlabpreview.md) can be used to display objects marked with `.servable()` in a new JupyterLab tab, circumventing any potential styling issue.\n", ":::" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 4 }