Package aquarium :: Package screen :: Module ScreenAPI
[show private | hide private]
[frames | no frames]

Module aquarium.screen.ScreenAPI

Document the API for screen classes.

Screens are the focal point of interaction with the user. In general, the URL controls which screen is shown. There are two types of screens: controllers and views. Controllers contain business logic and are written in Python. Views contain display logic and are written in Cheetah.


Controllers are responsible for:

Making changes in state:
For example, using a database module to insert a new row into the database is a change in state.
Conveying the results of the user's actions:
For example, "The item has been added to your shopping cart." or "Your credit card is invalid." In general, controllers whose main purpose is a change in state (e.g. add_item) should set actionResults (self._ctx.actionResults) to the appropriate message. See the aquarium.layout.LayoutAPI for more details. Controllers whose main purpose is to prepare data to be shown on a view (e.g. show_messages) should not set actionResults. This is not a rule, it's just an observation. You may choose to store actionResults in the session instead of ctx if you want it to survive redirects.
Preparing the data to be shown on a view:
Views are usually written in Cheetah, so as much work as possible is pushed into the controller where doing a lot of complex Python is more convenient. If a controller passes a single argument which is an instance of some class, that instance is called "the bean" (in fact, aquarium.layout.Bare will even save it as self.bean for your convenience). Since controllers must often do double duty (they change state as well as prepare for the view), the aquarium.screen.Controller superclass has a method named aquarium.screen.Controller.executeAction that can isolate state changing code in methods of the form doFooAction.
Choosing a screen to show:
Depending on the form parameters given to the controller, it may choose which screen to show next. This screen may be either a controller or a view. If a controller's main task is to prepare some data to be shown on some view, the controller will be named something like while the view will be named something like foo_view.tmpl. Note that I use lower case names because that is most common in URLs.
Forwarding processing to a screen:
Once the next screen to show is chosen, the controller directs processing to that screen via self._ctx.iLib.forward(screenModule, args...). Please note that this method does not return. Please see the documentation for aquarium.util.InternalLibrary.forward for more details.

As a last note, controllers are free to subclass any other subclass of aquarium.util.AquariumClass they want. However, it is common to first create a subclass of aquarium.screen.Controller and then make all of your controllers subclass that class.


Views are responsible for displaying content. Views encapsulate the main content returned as a result of some request. Views subclass layout classes. For instance, if the main content of a Web site is always in the middle, with navigation buttons along the top, each view in the Web site would subclass a layout named TopNav. Sometimes views are used to generate non-HTML content, such as an XML report. In such cases, it is customary to subclass the layout aquarium.layout.Bare.

Views that have a __call__ method that receives arguments (other than self) are not directly accessible from the outside. Trying to use a Web browser to request such a view directly will result in an exception. (When the layout tries to call the view's __call__ method without any arguments, a TypeError exception will occur.) This type checking is by design. Having Python enforce the API between the controller and the next screen is a real strength of Aquarium in contrast to JSP style forwards.

Other Details

The astute reader may wonder, "If I have view and controller, where is the model?" Aquarium enforces the use of controllers and views, but the distinction between controller and model is entirely up to the developer/application. You can make the controllers as "thin" or "heavy" as you wish.

Controllers and views are stored in the same directory because experience shows that if you're working on one, you'll probably want to work on the other. The modus operandi is to have a directory hierarchy that matches the hierarchy found in the URLs for the Web site. Within each directory views and controllers sit side by side.

Controllers and views have the same API in that both must implement a __call__ method:


Return the contents of this screen as a string or do a forward.

To support streaming very large or infinite amounts of data, instead of returning a string, __call__ may be a generator or return a generator. Note, however, that you can't easily do this in Cheetah because every Cheetah method implicitly does a return. See the echo screen for an easy way to use this feature.

Generated by Epydoc 2.1 on Mon Jan 1 16:34:19 2007