Developing Componentized Web Applications in the Twisted Framework

DOMTemplate solves the problem of separating logic from presentation, and allows the templating logic to be expressed in Python code form using the DOM API. However, the DOM API is too low level and it quickly becomes tedious to use to build complicated HTML structures.

Twisted's Solution

Twisted's soluton is to provide a Model-View-Controller based component framework, which allows you to construct complex HTML "Views" out of many small interacting components, or "DOMWidgets".

Instead of manipulating DOM objects which represent low-level HTML Nodes, you construct and compose views using widgets defined in twisted.web.domwidgets, and higher-level widgets that you define yourself for an application-specific purpose.

Model-View-Controller

Model View Controller is simply a development strategy which involves breaking up your program logic into three seperate domains: Model objects, whose job it is to contain data; View objects, whose job it is to present this data to the user; and Controller objects, whose job it is to interpret the input the user provides and update the model and view with the user's desired changes.

Twisted's implementation of MVC is deliberately simple, and is defined in twisted.python.mvc. twisted.python.mvc takes advantage of twisted.python.components, the interface and component registry, in order to loosely couple the interacting objects. A complete MVC triad definition looks like this:

from twisted.python import mvc
from twisted.python import components

MFoo(mvc.Model): pass
VFoo(mvc.View): pass
CFoo(mvc.Controller): pass

# Register VFoo as a View for MFoo
components.registerAdapter(VFoo, MFoo, mvc.IView)
# Register CFoo as a Controller for MFoo
components.registerAdapter(CFoo, MFoo, mvc.IController)

Although it is not always necessary to define a complete MVC triad, I recommend doing so initially even if your class bodies are simply 'pass'. This will get you used to thinking about MVC objects as a complete triad of cooperating objects, and make it easy to add functionality to your triad later.

DOMTemplate and DOMController

The View and Controller objects that Twisted defines know nothing about the web; thus, twisted defines subclasses DOMTemplate and DOMController for interacting with twisted.web, Twisted's HTTP server. twisted.web defines IResource, the interface that Resource objects must implement in order to support publishing themselves on the web. DOMTemplate and DOMController both support this interface, giving you an easy and powerful way to handle incoming web requests and generate template-driven web pages.

Here is an example MVC triad for the web:

from twisted.python import mvc
from twisted.web import domtemplate
from twisted.web import resource

class MExample(mvc.Model):
    pass
class VExample(domtemplate.DOMTemplate):
    resourceFile = 'Example.xhtml'
class CExample(domtemplate.DOMController):
    pass

# Register CExample as the Resource for MExample
# This will cause Controller.render(request) to be called
# when someone wants to view a MExample object.
components.registerAdapter(CExample, MExample, resource.IResource)
# Register VExample as a View for MExample
components.registerAdapter(VExample, MExample, mvc.IView)
# Register CExample as a Controller for MExample
components.registerAdapter(CExample, MExample, mvc.IController)