Genshi templates basics

Genshi is a Python templating system which guarantees correct XML output, and escapes all strings by default.

In exchange, you need to write more code and it is a bit of a pain to work with Unicode characters. Also, there is an extra step in case you do not want your strings to be escaped (i.e. you are passing good XML to the rendering mechanism). Here are some notes on the programming API, covering Genshi 0.5.1.

Streams

Most Python templating system (meaning Mako, Jinja2, Django) involve the use of two objects: some kind of lookup or loading or environment object, which you initialize with things such as the template directory location, and a template object. Basically, the factory pattern. Genshi is a bit more complex as the template object does not return strings but streams. Streams are sequences of events, similar to those defined in a SAX API. The theoretical advantage is that this API allows to chain any kind of filter on these streams (most XML manipulation APIs are built on top of an event based parser). The developers even repurposed the Python bitwise operator to achieve a syntax which looks like Unix pipes (!). There is built in support for selecting subsets using Xpath. When you call render on a stream object, you need to specify a format, by passing a string (one of 'html', 'xhtml', 'xml 'and 'text'). This is where the validation comes in, as there will be an error if Genshi cannot produce a valid document of that type. You might wonder what the difference is between 'xml' and 'xhtml'. From the official docs:

Rendering a template

To get a string you can print somewhere, you need to call a method on the stream object with a parameter to specify the kind of output you want. Three objects are involved: a template loader, which has methods that return template objects, templates objects (Template), which have methods outputting  streams, and stream objects, which you  have a render method. So before you get fit to print somewhere, you need to instantiate three objects. Suppose that your template is in mystuff/mytemplates/template.html. Before you can use a template, you need to instantiate a TemplateLoader

Then get a template

Then get a stream

Finally you get your string that you can print. Say you know that XHTML should come out:

Autoescaping

If you try to pass xml to the generate method of a template object, Genshi will escape eveything. To avoid this you need to wrap the string in a genshi.core.Markup instance. The string must again be a utf-8 string (see below)

UTF-8

If you need to use text which is utf-8 encoded, you need to use unicode strings everywhere, not raw byte strings. So if you read your strings from a file, call decode(utf-8) on the string, otherwise things will blow up.

Conclusion

Genshi looks a bit overkill for run-of-the-mill (read web) application; it seems to have been developed to generate XML documents from other XML documents. If this is not what you want (and workflows based on XML are not that hip anymore, but they are entrenched in many corporate and public sector bureaucracies), you might consider using a text based templating language.