# wt module

## Synopsis

The `wt` module provides an object-oriented HTML templating system. The design goals of the system were that it should be very simple, that it should involve very low overhead in terms of code repeated per page, that it should achieve as completely as possible the separation of code and data, and that it should promote modular code re-use.

## Sub-modules

The `wt` package contains the following sub-modules:

- `rowaccess` - class to automatically create replacements from a dictionary
- `textblock` - class to assist creation of text paragraphs

## Usage

The `wt` system expects you to supply two files for each page that is to be served - an HTML file and a code file. The conventional layout for this is to have a directory named `wt` in the root of your web tree, the directory structure inside which mirrors the structure of the web site outside the `wt` directory. For each file in the web site, the corresponding code file is under the `wt` hierarchy, with the same name but with `.py` appended. e.g. if you have an HTML file named `sales/index.html`, its code file would be named `wt/sales/index.html.py`.

The web server must be configured to pass requests through the `wt.Handler` request handler. Instructions on how to do this with Apache are included on the wt examples page.

## Templates

Template files contain only two constructs of interest to the `wt` system - replacements, and sections. Replacements are used where generated output should be inserted, and sections are used to divide the template into logical blocks. Each replacement corresponds to a method in a class in the code file, and each section corresponds to a nested class.

### Replacements

Replacements consist of two dollar signs followed by an identifier name (which may contain alphanumerics and underscore) and another two dollar signs - for example, `$$title$$`. You then supply a variable or method of the same name in the current section class, the value or return value of which will be output instead of the literal text of the replacement. Names beinning with an underscore are reserved.

By default, the value will be passed through `cgi.html_encode` before being output. Doing this by default simplifies programming since it is almost always the correct option. It also means that your code is secure by default against cross-site scripting attacks. (You must also make sure that the browser knows what character set you are using, but since `cgi.Request.__init__` automatically specifies the character set for you in the `Content-Type` header, you are secure by default here as well.)

To use another encoding, you can put an encoding specifier character before the identifier name. The two alternative encodings are `%` for `cgi.url_encode` (e.g. `$$%page$$`) and `=` to output the return value unchanged (e.g. `$$=html$$`). Care must be taken with the literal encoding to ensure that no unverified user input ends up being sent to the client's browser.

Example:

`<a href="article.html?id=$$%id$$">$$title$$</a>`

`class main(wt.TemplateCode):
def id(self): return 123
def title(self): return "this is the title"`

### Sections

Sections begin with an HTML comment containing only `wt:` and an identifier name (which may contain alphanumerics and underscore) - for example, `<!--wt:newsitem-->`. The section is ended by a similar comment but with a `/` before the identifier name - for example, `<!--wt:/newsitem-->`. All the data between the start and end markers is the content of the section. Sections can be nested, but you cannot nest a section inside another with the same name. Names beginning with an underscore are reserved.

The code corresponding to a section is a class subclassed from `wt.TemplateCode`. An instance of the class will be created and the section content passed to the `TemplateCode.main`. This new instance will be used to look for methods to satisfy replacements.

If you do not need the section to have any content, a combined start-and-end marker in the same comment is achievable by placing a `/` character after the identifier name - e.g., `<!--wt:_page/-->`. This is useful, for example, with `wt.GlobalTemplate` sections.

Please note that the start and end markers must appear exactly as described - no white space is allowed at any point inside the marker. `<! --wt:invalid-->` is not valid, for example.

For example:

`<!--wt:newsitem-->
<a href="article.html?id=$$%id$$">$$title$$</a>
<!--wt:/newsitem-->`

`class main(wt.TemplateCode):
class newsitem(wt.TemplateCode):
def id(self): return 123
def title(self): return "this is the title"`

## class: TemplateCode

The base class for all code corresponding to template sections.

### Public Instance Variables

#### `wt`

A reference to the `wt.Handler` instance which is handling this request.

#### `req`

A reference to the `cgi.Request` instance which contains information about this request.

#### `outer`

A reference to the `TemplateCode` instance which corresponds to the next outer-most section in the template - i.e. an instance of the class that this class is nested within. This is not the same thing as `super`, which is the class this class is derived from. If there is no enclosing class then `outer` is `None`.

### Public Methods

#### `process(self, template, selected=None)`

`template`: string
`selected`: `None`, or a string, or a sequence of strings

This method is called to process a template string. The `template` parameter contents the template to be processed. Variables and methods to satisfy replacements and classes to satisfy sections are looked for inside `self`.

If `selected` is `None` then all top-level sections in the template string are executed. If it is a string or sequence of strings then only top-level sections with a name matching that string or in that sequence will be executed, and sections with other names will be ignored and no output produced for them.

Template sections with the special name `_null` are ignored. The content of these sections is always discarded, regardless of the value of the `selected` parameter, and therefore no corresponding class is required in the code file.

#### `main(self, template)`

`template`: string

This method may be overridden by subclasses. The default implementation simply passes the `template` parameter, which is the contents of the section which caused this object to be created, to the `process` method.

A lot of the power of the templating system is provided by overriding this method. By redefining it you can cause the template section to be output multiple times, or not at all, or indeed ignore the `process` method altogether and do something entirely different with the `template` parameter. You can send output directly using the `write` method of the `self.req` variable.

Examples of the use of `TemplateCode` are given in the wt examples page.

## class: GlobalTemplate(TemplateCode)

A base class for template sections where the template is to be fetched from another source rather than be found in-line in the HTML file. The normal HTML contents of any section derived from `GlobalTemplate` are temporarily suspended and used for a subsection named `page` instead. A separate file is read to provide the HTML template for the `GlobalTemplate` section.

Examples of the use of `GlobalTemplate` are given in the wt examples page.

### Public Class Variables

#### `page`

This variable may be overridden by subclasses. A `TemplateCode` subclass which is called with the original template contents that would otherwise have been used for the `GlobalTemplate` class. The default value is `TemplateCode`. Due to the extra processing which `GlobalTemplate` interposes, the corresponding HTML template section to this class should be named `_page`, not `page`.

### Public Methods

#### `template_name(self)`

Returns: a string

This method may be overridden by subclasses. This method returns the filename to read to fetch the template contents for this section. The default implementation returns `self.wt.etc + "/template.html"`.

## class: Handler(cgi.Handler)

This `Handler` class should be called to process a request using the `wt` templating system. The default implementation uses various environment variables which will have been set up by the Apache configuration shown on the wt examples page to determine the code and template names, but various methods are provided which may be overridden to make these choices in a different way (for example, if you are using a different web server). All `wt.TemplateCode` objects receive a reference to the current instance in their `self.wt` instance variable.

### Public Instance Variables

#### `req`

A reference to the `cgi.Request` instance which contains information about this request.

#### `etc`

The directory `DOCUMENT_ROOT + "../etc"`. This is used as a default location by `GlobalTemplate.template_name` to locate templates. It is also a useful location to place miscellaneous files associated with a web site that should not be under the `DOCUMENT_ROOT`.

#### `template`

The full pathname of the template file.

### Public Methods

#### `pre_request(self, obj)`

`obj`: `wt.TemplateCode` instance

This method may be overridden by subclasses. Its default implementation does nothing. It is called just before `obj.main()` is called to process the request. All the instance variables of `self` have already been set up.

#### `post_request(self, obj)`

`obj`: `wt.TemplateCode` instance

This method may be overridden by subclasses. Its default implementation does nothing. It is called just after `obj.main()` has handled the request.

#### `process(self, req)`

`req`: `cgi.Request` instance

This method may be overridden by subclasses. It calls `self._get_template()`, `self._get_code()` and `self._get_etc()` to determine the various files and directories to use when handling the request. The code file should contain a subclass of `wt.TemplateCode` named `main`, which is passed the entire template file. The global namespace the code file is executed in is initialised to contain a reference to the `wt` module in the variable `wt`, thus avoiding the need to do `import jon.wt as wt` in every code file. See the wt examples page for how to set up Apache so that `wt` knows what's going on.

You can add code to run before and/or after every request by overriding this method and performing processing before and/or after calling the base `wt.Handler.process` base method.

Example:

`class Handler(wt.Handler):
def process(self, req):
self.session = session.Session(req, url=0)
wt.Handler.process(self, req)
self.session.save()
fcgi.Request({fcgi.FCGI_RESPONDER: Handler}).run()`

### Protected Methods

#### `_get_template(self)`

Returns: string

This method may be overridden by subclasses. It returns the full pathname of the template file to be used for this request. `self.req` has already been set up. The default implementation looks for an environment variable whose name matches `(REDIRECT_){0,4}WT_TEMPLATE_FILENAME`.

#### `_get_code(self)`

Returns: string

This method may be overridden by subclasses. It returns the full pathname of the code file to be used for this request. `self.req` and `self.template` have already been set up. The default implementation returns the environment variable `PATH_TRANSLATED`.

#### `_get_etc(self)`

Returns: string

This method may be overridden by subclasses. It returns the full pathname of the directory which `self.etc` will be set to. `self.req` has already been set up. The pathname should not end with a `/` character. The default implementation returns the equivalent of `DOCUMENT_ROOT/../etc`.

## class: DebugHandler(cgi.DebugHandlerMixIn, Handler)

This class is identical to `Handler`, except that it uses `cgi.DebugHandlerMixIn` so that if an exception is thrown by a template page then a traceback will be sent to the browser. This class may be used during development to aid debugging but should never be used in a production environment since it will leak private information to the browser.

$Id: wt.html,v 1.14 2003/04/16 10:53:28 jribbens Exp $