# wt module examples

## Synopsis

The `wt` module provides an object-oriented HTML templating system. This page contains examples of how to perform various common operations using `wt`.

## Apache Configuration

### Using `httpd.conf`

`wt` uses a dual-hierarchy system to separate and identify data (HTML) files and associated code files. This requires some configuration of the web server in order to allow it to provide the correct information to `wt`. An example configuration for Apache using mod_rewrite is shown below:

`<VirtualHost 192.168.0.1>
ServerName www.example.com
...
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/wt/$1.py -f
RewriteRule ^/(.*)$ /wt/$1.py [PT,E=WT_TEMPLATE_URL:/$1,E=WT_TEMPLATE_FILENAME:%{DOCUMENT_ROOT}/$1]
<Location /wt/>
Action wt-handler /cgi-bin/wt.py
SetHandler wt-handler
</Location>
</VirtualHost>`

The `RewriteCond` line means that the `RewriteRule` only takes effect if a code file corresponding to the currently-requested data file exists in the code directory hierarchy. This means that you can put ordinary static data files in the data directory hierarchy and they will be served to the user by the web server as usual without any intervention by `wt`.

The `RewriteRule` line rewrites the request URL, which originally identified the data file, to point to the code file instead. As it does this it stores information about the data file into environment variables for `wt.Handler.process` to retrieve later.

Finally the `<Location>` block uses normal Apache directives to tell the web server to execute the code files using `/cgi-bin/wt.py`, which is effectively the central despatch point for all `wt` pages within the site. The simplest possible version of this file would look as follows:

`#!/usr/local/bin/python
import jon.wt as wt
import jon.cgi as cgi
cgi.CGIRequest(wt.Handler).process()`

You can also perform global setup actions in this file, for example altering `sys.path[0]` to point to a directory where you place site-specific modules.

### Using `.htaccess`

If you do not have access to edit `httpd.conf` on your web server, you can set up the server for use with `wt` using `.htaccess` files instead. The way it works and your `/cgi-bin/wt.py` file are exactly the same as the `httpd.conf` case shown above, but the `mod_rewrite` commands are very slightly different.

You will need two `.htaccess` files. The first goes in the web root directory:

`RewriteEngine on
RewriteBase /
RewriteCond %{DOCUMENT_ROOT}/wt/$1.py -f
RewriteRule ^(.*)$ /wt/$1.py [E=WT_TEMPLATE_URL:/$1,E=WT_TEMPLATE_FILENAME:%{DOCUMENT_ROOT}/$1]`

The second `.htaccess` file goes in the `/wt/` subdirectory of the web root:

`Action wt-handler /cgi-bin/wt.py
SetHandler wt-handler`

### Using the `wt` and `session` modules together

See the `session` module documentation for how to configure Apache when using both the `wt` and `session` modules together.

## `TemplateCode` examples

### Simple replacements

This example simply displays the form variable `foo` as part of the output HTML. Note that it does not attempt to check whether or not a form variable called `foo` was actually passed to the server by the user's web browser, and Python will throw an exception if it wasn't. This is deliberate - if something "shouldn't happen" (e.g. if this page should never be called without a `foo` parameter unless the user has been inventing URLs) then just let an exception be thrown and caught by the top-level handler. If you do wish to check whether or not the parameter was passed then you can use `self.req.params.has_key` or `self.req.params.get`.

`<p>The 'foo' parameter is: $$foo$$.</p>`

`class main(wt.TemplateCode):
def foo(self):
return self.req.params["foo"]`

### Simple sections

This example mostly demonstrates just the syntax of a section. The section name in the HTML file corresponds to a nested class name in the code file. Obviously in a real world situation the `id` and `title` would not be static but would be calculated or fetched, e.g. from a database. Note also the way that the replacement inside a URL is done using the `%` encoding modifier so that the replacement text has any characters that would be special to URLs encoded.

`<!--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"`

### Overriding `main`

This example demonstrates overriding the `main` method of a section. In this case it simply decides whether or not to output the contents of the section depending on whether or not a form variable `show` was present in the request. The section could contain replacements and sub-sections as usual, although in this simple example it contains only text.

`<!--wt:section-->
...content goes here...
<!--wt:/section-->`

`class main(wt.TemplateCode):
class section(wt.TemplateCode):
def main(self, template):
if self.req.params.has_key("show"):
self.process(template)`

### Repeating sections

This example builds on the last to show how you can output a section multiple times, with different replacements each time. Again, in the real world you would presumably be fetching values from a database to display to the user.

`<!--wt:section-->
<p>This is paragraph number $$num$$.</p>
<!--wt:/section-->`

`class main(wt.TemplateCode):
class section(wt.TemplateCode):
def main(self, template):
for self.num in xrange(1, 11):
self.process(template)`

### Alternating sections

This example demonstrates the `selected` parameter to `wt.TemplateCode.process`. It also demonstrates subsections, and using inheritance to share code between sections. The main section is output ten times with incrementing values of `num`, but different subsections are used depending on whether the number is odd or even. When `self.process(template, "odd")` is called, only subsections called `odd` are output, all other sections are ignored completely (and their associated code classes are not called).

The other interesting point about this example is that, while the HTML for the `odd` and `even` sections are different, the code is similar. We save on duplication by defining a class called `subsec` which `odd` and `even` then subclass. The `num` method is thus shared between both while the `colour` class variable is overridden by `odd`.

`<!--wt:section-->
<!--wt:odd-->
<p style="border: solid $$colour$$">This is paragraph number $$num$$,
which is an odd number.</p>
<!--wt:/odd-->
<!--wt:even-->
<p style="border: solid $$colour$$">This is paragraph number $$num$$,
which is an even number.</p>
<!--wt:/even-->
<!--wt:/section-->`

`class main(wt.TemplateCode):
class section(wt.TemplateCode):
class subsec(wt.TemplateCode):
colour = "black"
def num(self):
return self.outer.num
class odd(subsec):
colour = "blue"
class even(subsec):
pass
def main(self, template):
for self.num in xrange(1, 11):
if self.num & 1:
self.process(template, "odd")
else:
self.process(template, "even")`

## `GlobalTemplate` examples

### Simple template

This example shows the simplest use of a `GlobalTemplate`. The first HTML file shown is placed in the `template.html` file in the `etc` directory. This HTML then does not need to be repeated for each individual page on the site, `wt` automatically outputs the template HTML with the individual page HTML inserted at the appropriate point. Therefore the individual page HTML files are not complete HTML files (i.e. they do not start with `<html>`), they are just the fragments required to complete the global template.

`<html><head>
<title>Title for every page</title></head>
<body><h1>Heading for every page</h1>
<!--wt:_page/-->
</body></html>`

`<p>This is an individual page.</p>`

`class main(wt.GlobalTemplate):
class page(wt.TemplateCode):
pass`

### Overriding `GlobalTemplate`

This example is a bit more interesting. The global HTML template contains a dynamic replacement. In the individual page code, the template class can be used unchanged, or `title` can be overridden to change the template on this page. In this way you simultaneously get the benefits of shared code for the global template, and the ability to override particular properties of the template on individual pages.

`<html><head>
<title>$$title$$</title></head>
<body><h1>Heading for every page</h1>
<!--wt:_page/-->
</body></html>`

`<p>This page is $$description$$.</p>`

`class template(wt.GlobalTemplate):
title = "Default title"
def template_name(self):
return self.wt.etc + "/our_template.html"
class main(template):
title = "Title for this page"
class page(wt.TemplateCode):
def description(self):
return "super"`

$Id: wt-examples.html,v 1.7 2002/08/12 10:32:17 jribbens Exp $