Component

Contents

Downloads and Websites

The repository is a Subversion repository. To check out a copy:

$ svn co http://svn.webwareforpython.org/Component/trunk Component

License and Prerequesites

Component is licensed under an MIT-style license. This gives you permission to most anything you want with Component.

Component is a toolkit for Webware For Python. Webware is the only prerequisite.

What Are They?

Many enhancements in Webware require subclassing WebKit.Page. But each of these enhancements is incompatible with the others, because you have to choose an specific inheritance hierarchy to use them. You can't subclass SecurePage and SidebarPage and MVCPage all at once.

One solution is Mixins, using multiple inheritance to add various functions. This technique is available in Webware through MiscUtils.MixIn. However, there are many places where Mixins are mutually incompatible -- for instance, code often has to intercept the awake() method, but delegating to each Mixin requires that they all know about each other.

Components are essentially a way of creating Mixins that all know about each other.

What's a Component Good For?

Components are useful if you have code that should know about the request and response, and possible intercept it. If the code doesn't need to know about the request at all, you should just create a normal Python library, and call into it explicitly. Components can also be a convenient way to add new convenience methods to your servlet.

Using CPage

In order to use components, all your servlets must inherit from Component.CPage. This subclass of WebKit.Page adds some new convenient methods, but mostly just adds component support.

New methods:

writeHeader():
Called automatically in writeBodyParts. If you are not using a template, this can be used to write the HTML that goes at the top of every page (the text written goes just after <body>).
writeFooter():
writeHeader compliment.
setView(view_name):
CPage adds the idea of views. The default view is writeContent -- that's the innermost method that is called. This can be used with actions so that the action method performs some work, then changes the view to display a different body. This way actions occur before content display, but can effect later display without losing the normal Python templating mechanism (writeHead, etc). Templating components (like ZPTKit) may use this concept of view to indicate a template to use.
view():
Returns the view, as a string.
sendResponseAndEnd(status, headers={}, body=None):

For error responses. This can be used like:

def awake(self, trans):
    CPage.awake(self, trans)
    try:
        self.id = int(
            self.request().extraURLPath().split('/')[1])
    except (ValueError, IndexError):
        self.sendResponseAndEnd(500)

A simple error body is created if you don't pass one in.

preAction and postAction are modified to do nothing (in WebKit.Page they output a little HTML).

Using Components

CPage looks for any components you have in the .components class variable (which should be a list). One very simple component is included, NotifyComponent. As an example you can use this component like:

from Component import CPage
from Component.notify import NotifyComponent

class SitePage(CPage):

    components = [NotifyComponent()]

    def writeHeader(self):
        self.writeMessages()

If the component was configured, it would probably take arguments to its constructor (this simple component has no configuration). A component can add new methods to the servlet. In this case it adds a .message(text) method, which adds your message to the session, and a .writeMessages() method which writes the messages and clears them from the session. (Also a .messageText() method if you don't want to write the messages immediately.)

It's up to the component to add methods or attributes to the servlet. It can also respond to "events" -- one example (and one of the only current events) is the awake event, where it could intercept the request. An example of this is in LoginKit, where the component checks the servlet for permission settings, and may abort the transaction with a login screen (or a Forbidden response) during awake().

Writing Components

Read the source -- there are many docstrings in Component.py.