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
View inherit all the common elements.
In a large
UserInterface it becomes cumbersome
to do what we’ve done with AddressBookPage. Moreover, what we did also
hard-codes the main layout (and usually, look) used for your
application in the code of the
UserInterface. As you will learn later on,
it is also possible to re-use other pre-existing
UserInterfaces as part of your web
application. Hard-coding the main page of a
UserInterface that is supposed to be re-used in
different web applications (that each may look different) obviously
won’t do either.
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
what it would add to the page.
To make this possible, there is a special Widget,
Slot. On its own, a
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 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
Slot of the page.
In “Page 2”, the same page is displayed, but with different
text in those
from __future__ import print_function, unicode_literals, absolute_import, division from reahl.web.fw import UserInterface from reahl.web.ui import HTML5Page, P, Menu, HorizontalLayout from reahl.web.pure import PageColumnLayout, UnitSize class MyCustomPage(HTML5Page): def __init__(self, view, bookmarks): super(MyCustomPage, self).__init__(view, style='basic') columns_needed = [('secondary', UnitSize('1/4')), ('main', UnitSize('3/4'))] self.use_layout(PageColumnLayout(*columns_needed)) menu = Menu.from_bookmarks(view, bookmarks) menu.use_layout(HorizontalLayout()) self.layout.header.add_child(menu) 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)
In the example, the
PageColumnLayout is used
to give our plain
HTML5Page a .header (which
we can use to put a menu bar) and two columns for content. The column
named “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
HTML5Page. That way the
PageColumnLayout can be applied to our
CustomPage, and a suitably laid out
Menu can be
added to the .header of all CustomPage instances.