# Component 0.2

Contents

- Downloads and Websites
- License and Prerequesites
- What Are They?
  - What's a Component Good For?
- Using CPage
- Using Components
- Writing Components

# Downloads and Websites

- Homepage: http://wiki.webwareforpython.org/component.html
- Download: http://webwareforpython.org/downloads/Component-0.2.tar.gz
- Source repository: http://svn.webwareforpython.org/Component/trunk
- Discussion: webware-discuss@lists.sourceforge.net

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`.