Multipage Application, Part 1

This is Part 1 of a two-part series about building multi-page applications in Taipy GUI. The series comprises of:

  • Part 1 – Building a Basic Multi-Page Application
  • Part 2 – Root Page and Bound Variable Scope

How to create a multi-page application?

 

Organizing the Code

Although it’s possible to create a multi-page Taipy application in a single script, we would usually want to organize our code to use a folder structure such as the following:

app/
├─ main.py
├─ pages/
│ ├─ home.py
│ ├─ temperature.py

In this layout, each submodule in the pages folder (home.py and temperature.py) contains the code for each page in our application. We use just 2 pages for this example, but naturally you can add as many as you want.

 

Defining the Pages

For simplicity’s sake, we will have each page be unrelated to each other — i.e., interacting with one page will have no influence on another page. We will cover interaction between pages in Part 2 of this series.

Take a look at the code for each of our page modules:

### home.py

from taipy.gui import Markdown

text = "Welcome to the Taipy multi-page tutorial app!"

home_md = Markdown("""
# Home

<|{text}|>
""")
### temperature.py

from taipy.gui import Markdown

def fahrenheit_to_celsius(fahrenheit):
    return (fahrenheit - 32) * 5 / 9

fahrenheit = 100
celsius = fahrenheit_to_celsius(fahrenheit)

temperature_md = Markdown("""
# Fahrenheit to Celsius

Don’t worry if you don’t understand every line of code! You just need to know that both pages are unrelated, and are doing their own thing, namely:

  1. The home_md page displays a welcome message; and
  2. The temperature_md page allows a user to convert a temperature from °F to °C.

Normally, if we were creating a simple one-page application, we would pass one of our pages (Taipy Markdown or Html objects) to the taipy.gui.Gui constructor. For example, we could add the following lines to home.py to turn it into a one-page Taipy application:

### home.py, as a standalone one-page app

from taipy.gui import Markdown, Gui

# same code as before

home_md = Markdown(…) # same content as before

Gui(page=home_md).run() # or simply, Gui(home_md).run()

Defining a Multi-Page Application

So far, we’ve organized our multi-page Taipy application by storing two one-page applications in a subfolder which we called pages.

The next step is to define our main module (main.py) in the app directory and initialize our multi-page Gui object:

### main.py

from taipy.gui import Gui
from pages.home import home_md
from pages.temperature import temperature_md

pages = {

“home”: home_md,
“temperature”: temperature_md,

}

Gui(pages=pages).run(dark_mode=False)

The first thing we did was to import the two Markdown objects (home_md and temperature_md) from the two scripts which we had made. Then, we created a dictionary named pages:

    1. The dictionary key indicates the URL at which the page will be accessed; and
    2. The dictionary value is the Markdown object for that page.

Finally, we pass the pages dictionary to the pages parameter of the Taipy Gui object. Call its run method, and you have your first Taipy multi-page application up and running!

Opening your browser to localhost:5000 (assuming the default port is used), we see the following:

Taipy home application example

We are automatically directed to the /home URL since it was the first page in the pages dictionary, where we see our first page!

Now, if we modify the URL from /home to /temperature, we instead see the following:

Temperature

How to navigate between pages?

We certainly don’t want to be manually changing our URL to navigate between different pages. Taipy offers various approaches for adding navigation to your multi-page application.

 

1. The navbar

multipage navigation bar 2<br />

A simple way to add attractive navigation to your application is by using the Taipy navbar control. You can add the navbar to the home page by adding a single line to the top of the home_md page definition:

### home.py, with navbar

from taipy.gui import Markdown

text = "Welcome to the converter app!"

home_md = Markdown("""
<|navbar|>

# Home

<|{text}|>
""")

By default, the navbar control automatically creates an entry for each page in the pages dictionary, requiring no further required specification of properties — making it a quick and easy way to add navigation.

However, the code change above only added a navbar to the home_md page — we would still need to make the same change to temperature_md and any other page we have in our application. A better alternative that doesn’t require any code modification in any of the pages is to add a root page.

Navbar with Root Page

Rather than modifying each page to include the navbar, we can also simply modify main.py to utilize the root page:

### main.py, with root page navbar

from taipy.gui import Gui
from pages.home import home_md
from pages.temperature import temperature_md

pages = {
    "/": "<|navbar|>",
    "home": home_md,
    "temperature": temperature_md,
}

Gui(pages=pages).run(dark_mode=False)

Because every page inherits the root page, by adding a single line to main.py, every page now inherits the navbar control. As a bonus tip, we can also enclose the navbar control with HTML center tags to center the navbar to the middle of the page as follows: “<center><|navbar|></center>".

The root page is a fairly advanced concept in Taipy GUI, and will be explored further in Part 2 of this Taipy multi-page series. 

2. The navigate function

The taipy.gui.navigate function is self-explanatory in its purpose — it is used to navigate to other pages. For example, this is a code snippet of the navigate function being used to navigate to the home page when the button control is clicked:

from taipy.gui import navigate

md = "<|Click to go Home|button|on_action=go_home|>"
def go_home(state):
    navigate(state, "home")

Naturally, this function is only used within callbacks. To use navigate, we simply pass along the state variable present in all callbacks, as well as the name of the page we wish to go to. In the example above, the user will be directed to the /home page.

The navigate function provides a lot of flexibility to the developer to manage navigation in the application beyond what the navbar offers. For example, we can manage:

    1. After executing some process, direct the user to either the /success or /failure page depending on the process status; or
    2. Direct the user back to the /home page when an exception occurs (by using navigate in [on_exception](<https://docs.taipy.io/en/latest/manuals/gui/callbacks/#exception-handling>)).

As a Navbar Replacement

If we like, we could also replicate the functionality of the navbar, by using navigate with some other control (such as a selector control or tree control). In this example, let’s combine navigate with the menu (a collapsible side panel) control to produce the following app:

Multipage menu with Taipy

The menu navigation was implemented by modifying main.py to the following:

### main.py, with menu navigation

from taipy.gui import Gui, navigate
from pages.home import home_md
from pages.temperature import temperature_md

pages = {
    "/": "<|menu|lov={page_names}|on_action=menu_action|>",
    "home": home_md,
    "temperature": temperature_md,
}
page_names = [page for page in pages.keys() if page != "/"]

def menu_action(state, id, action, payload):
    page = payload["args"][0]
    navigate(state, page)

gui = Gui(pages=pages)
gui.run(dark_mode=False, run_browser=False, use_reloader=True)

Unlike navbar which automatically populates its lov (list of values) with the page names and intrinsically navigates the user to the selected page when it is interacted with, the code example above using the menu control and navigate is a little more verbose.

We define two properties for the menu control:

    1. lov={page_names} : The list of values which may be selected from the menu. In this case, we interpolate the page_names variable, which we then assign the keys from pages (other than “/") — functionally equivalent to page_names = [”home”, “temperature”]. Refer to the *menu* documentation for more details, such as for setting icons and labels.
    2. on_action=menu_action : Assigns the menu_action function as the callback function which is executed when the user clicks an item from the menu.

 

We define the menu_action function with the parameters as stated in the menu control documentation, then call navigate(state, page) to direct the user to the selected page. In practice, we effectively have the same functionality as the navbar, but had to do a bit more work to expressly create that functionality.

 

3. Hyperlinks

Finally, the simplest way to implement navigation in Taipy GUI is with a hyperlink:

### home.py, hyperlink to temperature

from taipy.gui import Markdown

home_md = Markdown("""
# Home

Go to [temperature](/temperature) page.
""")

This results in the following clickable “temperature” text, which directs the user to the /temperature URL:

Hyperlink

Part 2

As a preface to Part 2 of this Taipy Tips: Building a Multi-Page Application series, you can expect to read about the following things:

    1. Accessing state variables in more than one page (allowing for cross-page interaction);
    2. Understanding how Taipy GUI looks for variables and functions used in the Markdown page; and
    3. Code examples.
Zaccheus Sia
Zaccheus Sia

Data Scientist at Knowledge Touch Pte Ltd