Layout example

Several special widgets are provided to help position elements on a page. The example presented here shows some of these widgets in action.

The source code given below results in the following visual layout:

Screenshot of a page with header, footer, two columns and a few other layout features demonstrated.

The first thing to notice in the code given below is that the page used is not specified per View, but a single page is used for the entire UserInterface. Each View (there’s only one here) just specifies some contents for the named Slots provided by that page. (See Make light work of similar-looking pages for an explanation.)

Although you can roll your own, Reahl includes, for example, a TwoColumnPage which takes care of the basic layout of pages. In this example text is inserted to show the different areas which can be populated when using a TwoColumnPage.

Widgets like the LabelledBlockInput can be used to do the internal layout of elements of a form. A LabelledBlockInput wraps around any simple input and provides it with a label. It also positions all the relevant constituent elements neatly — including possible validation error messages.

Lastly, for users familiar with YUI-style layout grids, widgets are provided representing these lower-level layout tools.

from __future__ import print_function, unicode_literals, absolute_import, division
from reahl.web.fw import UserInterface
from reahl.web.ui import TwoColumnPage, Form, TextInput, LabelledBlockInput, P, YuiGrid, YuiUnit
from reahl.component.modelinterface import exposed, Field, EmailField

def lots_of(message):
    return message * 5

class LayoutUI(UserInterface):
    def assemble(self):
        self.define_page(TwoColumnPage, style='basic')  

        home = self.define_view('/', title='Layout demo')
        home.set_slot('main', CommentForm.factory())

        home.set_slot('secondary', P.factory(text=lots_of('The secondary column sits on'
                                                   ' the left side of the main column. ')))
        home.set_slot('header', P.factory(text=lots_of('This text is located in the header,'
                                                'which is provided for in a TwoColumnPage. ')))
        home.set_slot('footer', P.factory(text=lots_of('The footer spans the bottom of all the '
                                                'columns on a TwoColumnPage ')))

class Comment(object):
    def fields(self, fields):
        fields.email_address = EmailField(label='Email address', required=True)
        fields.text = Field(label='Comment text')

class CommentForm(Form):
    def __init__(self, view):
        super(CommentForm, self).__init__(view, 'myform')

        comment = Comment()
        self.add_child( LabelledBlockInput(TextInput(self, comment.fields.email_address)) )
        self.add_child( LabelledBlockInput(TextInput(self, comment.fields.text)) )

        row = self.add_child(YuiGrid(view))
        [left_unit, right_unit] = row.add_children([YuiUnit(view, first=True), YuiUnit(view)])

        left_unit.add_child( P(view, text='This is in the left block of the row') ) 
        right_unit.add_child( P(view, text='This is in the right block of the row') ) 

Previous topic

Validating user input

Next topic

Reacting to user events