Reusing a single page for a whole UserInterface

A page with varying contents

Up to now all the pages of an application were made to look similar by deriving each page from a common superclass.

There is an easier way.

An UrlBoundView can plug different contents into the same page provided that that page contains placeholders, called Slots. Each Slot on a page is referred to by name.


A page with two different views.

Below is an example application with two UrlBoundViews that re-use the same page. The home page looks as follows:


“Page 2”, looks the same, but with different text in the Slots:


Create a page with Slots

MyCustomPage calls with_slots() to let the PageLayout create a Slot inside each added column:

class MyCustomPage(HTML5Page):
    def __init__(self, view, bookmarks):
        super(MyCustomPage, self).__init__(view)

        contents_layout = ColumnLayout(ColumnOptions('secondary', size=ResponsiveSize(md=3)),
                                       ColumnOptions('main', size=ResponsiveSize(md=9))).with_slots()

        menu = Nav(view).use_layout(TabLayout()).with_bookmarks(bookmarks)

Define views in terms of Slots

MyCustomPage is defined as a single UserInterface-wide page with the call to define_page(). Call set_slot() to define how each UrlBoundView populates the placeholders.

The arguments expected by the __init__ of MyPage are passed along in the call to define_page().

class SlotsUI(UserInterface):
    def assemble(self):

        home = self.define_view('/', title='Page 1')
        home.set_slot('main', P.factory(text='In this slot will be some main content for the view on /'))
        home.set_slot('secondary', P.factory(text='Some secondary content related to /'))

        another = self.define_view('/page2', title='Page 2')
        another.set_slot('main', P.factory(text='This could, for example, be where a photo gallery shows a large photo.'))
        another.set_slot('secondary', P.factory(text='Thumbnails will then sit on the side of the big photo.'))

        bookmarks = [home.as_bookmark(self), another.as_bookmark(self)]
        self.define_page(MyCustomPage, bookmarks)