Now we are going to illustrate STL with a more complex example. Building up on the Task Tracker from the Chapter 4.4, we are going to write a method that produces an HTML page showing all the tasks.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:stl="http://xml.itools.org/namespaces/stl">
<head></head>
<body>
<h2>Task Tracker</h2>
<stl:block stl:repeat="task tasks">
<h4>
#${task/id}: ${task/title} (<em>${task/state}</em>)
</h4>
<p>${task/description}</p>
</stl:block>
</body>
</html>
def view(self):
# Load the STL template
handler = get_handler('TaskTracker_view.xml')
# Build the namespace
namespace = {}
namespace['tasks'] = []
for i, task in enumerate(self.tasks):
namespace['tasks'].append({'id': i,
'title': task.title,
'description': task.description,
'state': task.state,
'is_open': task.state == 'open'})
# Process the template and return the output
return stl(handler, namespace, mode='xhtml')
The output may be something like (depends on the content of self.tasks):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type"
content="application/xhtml+xml; charset=utf-8"/>
</head>
<body>
<h2>Task Tracker</h2>
<h4>
#0: Re-write the chapter about writing handler classes.
(<em>closed </em>)
</h4>
<p>A new chapter...
The Figure 9.2 shows how the HTML may look with a browser.
In the latter example, we have called STL with a mode parameter. By default STL returns a stream of events like "element is opening", "text", element is closing". When using the xhtml mode, STL will return a valid XHTML document as a Python string. There is also an html mode returning an HTML document with forbidden end tags omitted, e.g. <br> instead of the invalid <br/>.
The reason we use the stream mode by default is that STL will not accept to interpret (X)HTML content by default, thus protecting from unexpected code injection. STL will however accept streams and merge them into the ouput. To inject an (X)HTML string, you must first parse it using the XMLParser or HTMLParser.
In the real world, we compute and combine several templates, for instance a generated form into a page into a website layout, and only the final stl call would be asked for an html output (valid XHTML support is still little spreaded).
If you are interested in streams, see the Section 16.1 in the XML chapter.