As discussed in chapter 1, program logic is divided into actual program code and code that merely formats results. The former is put in a handler, the latter in a template. In this section we'll take a closer look at the two and write our first Draco program using these concepts.
All handler code is grouped per directory under the document root and put in a file named __handler__.py3.1. This file is a Python source file which we'll call the directory handler. In this directory handler we can define handler functions for templates in that directory. These functions are run by Draco before parsing the corresponding template and their job is to perform the action requested by the user. The results of this action are then passed on from the handler to the template, which can nicely format them into the html. How to define a handler function for a specific template is best shown by an example:
from draco.handler import Handler class MyHandler(Handler): def index(self, path, args): self['greeting'] = 'Hello, world!'
Let's discuss the above code fragment. To define a handler function for a template, you need to subclass the class Handler (defined in draco.handler), and put it in a file named __handler__.py. Methods defined in this handler class correspond to templates with the same name plus the default extension. So in the above example, we have defined a handler function for the template index.dsp.
As you see, the index method is defined with two extra arguments
with the canonical names path and args. This is true for all
handlers in Draco. These two arguments further specify the HTTP request.
The first argument is a Python list that contains the path components of the
url that were given after the template name, while the second
argument is a namespace that contains the HTTP GET and POST parameters. For
example, if a request for the url /index.dsp/test/me?foo=bar is made,
the index handler function will be called with a path of
['test', 'me']
and an args of {'foo': 'bar'}
.
The example illustrates another important concept in Draco: the interface. The interface is a namespace and is the way to pass results from a handler function to its corresponding template. We see that variables can be added to the interface using the Python dictionary API on the Handler instance. The variable is now directly available to the Python code in the template. This way, arbitrary Python variables can be exported, including more complex types like lists, dictionaries and classes.
Let's continue with the template. A template is a file containing HTML
with embedded code blocks. The code blocks contain Python code that should
format the results passed on from the handler. Code blocks are separated from the
html with the special <%
and %>
markers. The following
template formats the variable greeting that we set in the handler
above.
<html> <head> <title>My first Draco application</title> </head> <body> <p> <% print greeting %> </body> </html>
If you put this fragment in a file called index.dsp in the same directory as the above handler, you will be greeted again.