3.4. Understanding CherryPy and TurboGears Controllers
At the center of a TurboGears application is CherryPy, responding to every user action and sending changes to the model and view.
In other words, CherryPy provides the controller part of the MVC paradigm in TurboGears, and that means that it is responsible for parsing user actions and passing state-change requests to your model objects. It also calls the view template and can pass it whatever data it needs to present to the user.
It sounds like a lot, but actually TurboGears makes writing controllers easy.
Although views can pull data from the model, many people prefer to gather up whatever the view needs and pass it into the view as a dictionary.
There are legitimate reasons to move this kind of logic from the view into the controller. For one thing, the less code you have in your view, the easier it is to get a designer to work with you on those pages. Also, you may need to package the same data for several different output formats (HTML, XML-RPC, JSON, and so on), and it helps to keep the data access logic centralized in a single controller.
By default, TurboGears creates a file controllers.py for your controller classes in the application sub-directory whenever you use tg-admin quickstart to create a new project.
Because a web-based application encapsulates every single user action into an HTTP Get or HTTP Post request, our controller layer needs to listen for those requests, interpret them, and call the appropriate method, passing in the appropriate parameters.
The good news is that CherryPy and the TurboGears framework take care of most of this work for you.
For example, CherryPy takes every incoming request, tries to match it up to the object hierarchy in your controller classes, and calls the appropriate method. Oh, and for good measure, it passes in any parameters that were embedded in the HTTP request.
We saw this in Chapter 2, "Getting Started with TurboGears," when we created the "hello" method. We requested http://localhost:8080/hello, and the hello method was called. If you created the goodbye method, the same thing happened there.
Let's take a look at some sample code that bypasses Kid templates and sends output directly to the browser:
class Root(controllers.RootController): @expose() def index(self, name="John Carter"): return "I am %s, of Virginia" % name
Okay, so there's one more thing you have to understand to effectively use controllers in TurboGears, and that's the @expose() decorator. If you are new to Python, or just haven't used decorators before, this is easy.
TurboGears provides several decorators for controller methods. We talk about Turbo-Gears Decorators in depth in Chapter 17, "CherryPy and TurboGears Decorators," but we can get going with just @expose.
@expose provides a quick and easy method for you to use to say whether that particular method is public or private. You can also provide a view template that can be used to display the data your controller returns.
The syntax is simple, enabling you to expose a controller method to the web with one line:
@expose() def index(self): pass
And if you want to send that to the index.kid template, you can do it by adding the name and location (in standard Python dotted notation) to the .expose decorator like this:
@expose(template="project_name.templates.index") def index(): pass
Where project_name is the name of your project!