# The Superpage!

## SuperPage.py

### Why write a Page superclass?

After working on this application and learning woven for a few days, I noticed that most of the Pages I was writing had some similar characteristics. One of the more difficult issues I've faced when designing web sites is page-to-page consistency. Since all of the viewable pages in this application subclass SuperPage, it's easier to make site-wide changes in one place.

Now, mind you, that all of this is going on behind the scenes in the /home page (because it subclasses SuperPage), so if you were trying to figure out why there was no rendering code in WovenHome, here's your answer.

#### Code Listing - SuperPage.py

#### Code Listing - templates/superpage.html

## Models and Views

### Customize your Models

Well, one thing to notice right off the bat is that all of the wmfactory_*'s on the page are incredibly simple, just one or two lines. One of the real strengths of woven is that you can use any object as your model, As long as you write your view to understand it. For this program, I wrote several page-specific models, and several general models so that code that renders the view would be more sensible in the Page. (more on that later)

### The Bookmark Object

As we're building a site that reads bookmark data from a source and renders it into links on web page, the most basic data model would have to be a single instance of a bookmark.

This class is one of the new-style classes that works with Python 2.2 and later, because it subclasses object. The main reason we do this is to give us the ability to use Properties, which are something like Java's beans. Properties allow you to define special getter and setter methods for class attributes. This allows better performance than when overriding __setattr__, and without the potential implementation difficulties frequently encountered when trying to override __getattr__ in a class definition. If you haven't ever seen this before you may want to review Unifying types and classes in Python 2.2 by the BDFL (Guido van Rossum), and especially the section Properties: attributes defined by get/set methods.

We use this capability in the method _get_csv_row(), which is used by the CSVStorage class to get a representation of a particular Bookmark instance so it can be saved to disk in a flat file. Implementation of a property is very easy, you define a getter method, a setter method, and/or a deleter method (usually marking them as private by following the prepend a '_' to the method name convention), and then binding the property(getter, setter, deleter, docstring="") to attribute name you want.

Important Note: You don't supply a self. in front of the functions inside property(). This is because you're defining this property for the class, and at the time property() is called, the getter, setter, and deleter are function objects, and are not class methods.

next | prev | toc