The Output Class Hierarchy

E
very Output class is a subclass of Output, and has a single method: render(). This method returns the HTML representation of the object as a string.

Rendering is triggered by calling the render_output(oo) function in the utils.output module, with an output object oo as argument. This function accepts output objects, lists of output objects, and plain old Python strings (which are returned verbatim). This makes it possible to include strings in the output without a special wrapper class.

The thing that makes Output objects so powerful is that most of them are containers. Container is a subclass of Output which adds a member variable, suboutputs. This variable contains a list of output objects that are "inside" the container. A container's render method concatenates the results of rendering each of the container's suboutputs. The Container class also has all the functions of a Python list, such as c.append(foo), len(c), c.insert(0, bar), etc.

Containers are not particularly useful for wrapping tags around some text: it's usually easier to just put three output objects into the parent container: the start tag, the text, and the end tag. (opposite day? NAR)

Containers are useful for more complicated formatting. The EnglishList class (in utils/output/html.py) provides an instructive example. This Container subclass formats its suboutputs as an English list, by putting commas and the word `and' between individual suboutputs. This class is a simple, complete abstraction of the rules for English lists, freeing other code from the burden of (re)implementing these rules.