Make light work of similar-looking pages¶
There are common user interface elements present on all the different URLs of a web application. Our previous example is the first one with more than one page. We dealt with the commonality between its pages by having a common class (AddressBookPage) from which the page used by each View inherit all the common elements.
In a large UserInterface it becomes cumbersome to do what we’ve done with AddressBookPage. Later on you will also learn how to incorporate other pre-existing UserInterfaces as part of your own UserInterface. Obviously if the look and layout of the pages of a UserInterface are hard-coded like we’ve done with our example, you would not be able to incorporate it onto your web application, which has its own look and layout!
Slots and Views without pages¶
For all these reasons, there’s another way to deal with many pages that look similar: You can attach a page to the entire UserInterface instead of to each individual View inside it. Then you only need to specify as part of each View what it would add to the page.
To make this possible, there is a special Widget, Slot. On its own, a Slot does not render anything at all on the page it is a part of. It represents an empty area, the contents of which is meant to be supplied by a View. The View then “plugs” only the bit of content specific to it into the supplied Slot, on the fly.
There can be more than one Slot on a page, and each one of then is referred to individually by name.
See it in action¶
Below is the source code for an application that demonstrates these ideas.
The home page looks as follows:
Notice the two bits of text. Each paragraph was plugged into a separate Slot of the page.
In “Page 2”, the same page is displayed, but with different text in those Slots:
from __future__ import print_function, unicode_literals, absolute_import, division from reahl.web.fw import UserInterface from reahl.web.ui import TwoColumnPage, P, HMenu class MyCustomPage(TwoColumnPage): def __init__(self, view, bookmarks): super(MyCustomPage, self).__init__(view, style='basic') self.header.add_child(HMenu.from_bookmarks(view, bookmarks)) 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)
A TwoColumnPage is a handy Widget, since it contains a sensible page with all sorts of sub-parts to which one can attach extra Widgets. Of interest here are its .header element (a Panel positioned well for holding things like menu bars), and two of its predefined Slots: “main” and “secondary”. These two slots represent the two columns of the TwoColumnPage Widget: “main” is to the right, and fairly large, whereas “secondary” sits to the left of it, and is narrower.
In this example, a CustomPage is derived from TwoColumnPage. That way the CustomPage inherits all the abovementioned niceties from TwoColumnPage. To ba a useful page for this application, CustomPage only needs to add an HMenu to the .header of the TwoColumnPage on which it is based.