4.6 Building Applications with Page Modules

#
4.6 Building Applications with Page Modules

Implementing an application as a monolithic program is fine for small applications. As the application grows the startup time becomes an issue, as does maintenance. Albatross provides a set of classes that allow you to implement each page in a separate Python module. In this section we will convert the `popview` application to this type of application.

Converting a monolithic application to a page module application is usually fairly simple. First we must turn each page object into a page module. When we used page objects, the class that implemented each page was identified by the `name` class member. With page modules the name of the module identifies the page that it processes.

The complete sample program is contained in the `samples/popview4` directory. Use the `install.py` script to install the sample.

    cd samples/popview4
    python install.py

The `LoginPage` class becomes `login.py`.

    import poplib

    def page_process(ctx):
        if ctx.req_equals('login'):
            if ctx.locals.username and ctx.locals.passwd:
                try:
                    ctx.open_mbox()
                    ctx.add_session_vars('username', 'passwd')
                except poplib.error_proto:
                    return
                ctx.set_page('list')

    def page_display(ctx):
        ctx.run_template('login.html')

The `ListPage` class becomes `list.py`.

    def page_process(ctx):
        if ctx.req_equals('msgnum'):
            ctx.set_page('detail')

    def page_display(ctx):
        ctx.open_mbox()
        ctx.run_template('list.html')

And the `DetailPage` class becomes `detail.py`.

    def page_process(ctx):
        if ctx.req_equals('list'):
            ctx.set_page('list')

    def page_display(ctx):
        ctx.open_mbox()
        ctx.read_msg()
        ctx.run_template('detail.html')

When using page modules we do not need to register each page module. When Albatross needs to locate the code for a page it simply imports the module. So the entire `popview.py` program now looks like this:

    #!/usr/bin/python
    from albatross import ModularSessionApp, SessionAppContext
    from albatross.cgiapp import Request
    import popviewlib

    class AppContext(SessionAppContext):

        def open_mbox(self):
            if hasattr(self.locals, 'mbox'):
                return
            self.locals.mbox = popviewlib.Mbox(self.locals.username, self.locals.passwd)

        def read_msg(self):
            if hasattr(self.locals, 'msg'):
                return
            self.locals.msg = self.locals.mbox[int(self.locals.msgnum) - 1]
            self.locals.msg.read_body()

    class App(ModularSessionApp):

        def __init__(self):
            ModularSessionApp.__init__(self,
                                       base_url='popview.py',
                                       module_path='.',
                                       template_path='.',
                                       start_page='login',
                                       secret='-=-secret-=-',
                                       session_appid='popview4')

        def create_context(self):
            return AppContext(self)

    app = App()

    if __name__ == '__main__':
        app.run(Request())