Templess Examples

The examples below are valid for Templess 0.3 (current Subversion version), but apply also to the current release (0.2).

All of the examples below assume we're in a script with the following lines in the top somewhere:

    >>> from templess import templess

Example 1: simple interpolation

As a first example we'll interpolate the text 'bar' into a node 'foo' in a simple XML document.

    >>> xml = """\
    ... <?xml version="1.0" ?>
    ... <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
    ...   <foo t:content="foodata" />
    ... </doc>
    ... """
    >>> context = {
    ...     'foodata': 'bar',
    ... }
    >>> t = templess.template(xml)
    >>> print t.render_to_string(context)
    <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
      <foo>bar</foo>
    </doc>

On calling 'render()' the template is searched for any Templess directives, and at some point finds the 't:content' one. When this happens, it will look in the context passed in as an argument if there's a key for the value of the attribute. In our case the value of the attribute is 'foodata', so it will look for the key 'foodata', and will find the value 'bar'. Since this value is a string type, it will set it as the text value for the node, and remove the attribute when it's done.

Note that if the directive used would have been templess:replace, the doc element would get the text contents, and the foo node would have been removed, so the XML would look something like <doc>bar</doc>.

Example 2: node interpolation

In this example we'll interpolate a new XML node into the document. This functionality provides a simple way to re-use templates.

Note that (XXX currently?) the node needs to be a special Templess node to be interpolated. More convenient ways to add a node (either using an API that is less Templess specific, or perhaps by allowing XML nodes from other libraries) will be made available in the future.

    >>> xml = """\
    ... <?xml version="1.0" ?>
    ... <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
    ...   <foo t:content="foodata" />
    ... </doc>
    ... """
    >>> context = {
    ...   'foodata': templess.elnode('bar', {}, None),
    ... }
    >>> t = templess.template(xml)
    >>> print t.render_to_string(context)
    <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
      <foo><bar /></foo>
    </doc>

Exactly the same happens as with a string, except that instead of setting the text value of the node to the string value of the context, the element node will be used as the new content of the node.

A somewhat more useful example interpolates the results of another template (somewhat similar to macros in other systems)::

    >>> xml_bar = """\
    ... <?xml version="1.0" ?>
    ... <bar xmlns:t="http://johnnydebris.net/xmlns/templess"
    ...      t:content="bardata" />
    ... """
    >>> context_bar = {
    ...   'bardata': 'baz',
    ... }
    >>> t_bar = templess.template(xml_bar)
    >>> xml = """\
    ... <?xml version="1.0" ?>
    ... <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
    ...   <foo t:content="foodata" />
    ... </doc>
    ... """
    >>> context = {
    ...   'foodata': t_bar.render(context_bar)
    ... }
    >>> t = templess.template(xml)
    >>> print t.render_to_string(context)
    <doc xmlns:t="http://johnnydebris.net/xmlns/templess">

Example 3: list interpolation with string values

In this example we'll repeat a certain element inside the document, and interpolate the contents of an array into each instance.

    >>> xml = """\
    ... <?xml version="1.0" ?>
    ... <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
    ...   <foo t:content="foodata" />
    ... </doc>
    ... """
    >>> context = {
    ...   'foodata': ['foo', 'bar'],
    ... }
    >>> t = templess.template(xml)
    >>> print t.render_to_string(context)
    <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
      <foo>foo</foo><foo>bar</foo>
    </doc>

When the Templess engine notices the value is a list type, it will iterate through it, creating a clone of the node for each iteration. From there on the interpolation works exactly the same as normal, but then on the clone instead of on the original node. When it's done iterating the list, the original will be removed.

Note: the interpolation of nodes (templess.node subclasses) works exactly the same, also it's possible to use templess:replace the same way as before.

Note: when the values of the list are not of a string type, interpolation will not behave the same on the node, see the next example.

Example 4: list interpolation with dict values

In this example we'll use dict values for the list, effectively recursing into the interpolation process. The context for the recursion is the current context value (the current dict), and the root for the recursion is the current element.

    >>> xml = """\
    ... <?xml version="1.0" ?>
    ... <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
    ...   <foo t:content="foodata"><bar t:content="bardata" /></foo>
    ... </doc>
    ... """
    >>> context = {
    ...   'foodata': [
    ...     {'bardata': 'baz'},
    ...     {'bardata': 'qux'},
    ...   ],
    ... }
    >>> t = templess.template(xml)
    >>> print t.render_to_string(context)
    <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
      <foo><bar>baz</bar></foo><foo><bar>qux</bar></foo>
    </doc>

Of course this also works the same with templess.node instances instead of strings, and recurses infinitely, so you could use lists as the values, too. Also behaves as you'd expect when the directive is t:replace.

Example 5: conditional rendering

Very simple example for conditional rendering, because it's a very simple directive. The end result would be something like <doc><bar /></doc>.

    >>> xml = """\
    ... <?xml version="1.0" ?>
    ... <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
    ...   <foo t:cond="foodata" /><bar t:cond="bardata" />
    ... </doc>
    ... """
    >>> context = {
    ...   'foodata': False,
    ...   'bardata': True,
    ... }
    >>> t = templess.template(xml)
    >>> print t.render_to_string(context)
    <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
      <bar />
    </doc>

When the t:cond resolves to True, the element is left in tact, when it resolves to False, it's removed entirely from the document. There is a counter directive called 'not', which has exactly the opposite effect from 'cond', so instead of adding the node on a True value, it removes it.

Example 6: setting attributes

Setting attributes is also not too hard. The 'attr' directive generates attributes for each contained item, using the value in the context as value for the attribute. If the context value resolves to False, the attribute is skipped (unless the value is , then it will result in an empty attribute).

    >>> xml = """\
    ... <?xml version="1.0" ?>
    ... <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
    ...   <foo t:attr="bar bardata; baz bazdata; qux quxdata" />
    ... </doc>
    ... """
    >>> context = {
    ...   'bardata': 'quux',
    ...   'bazdata': 'quuux',
    ...   'quxdata': False,
    ... }
    >>> t = templess.template(xml)
    >>> print t.render_to_string(context)
    <doc xmlns:t="http://johnnydebris.net/xmlns/templess">
      <foo bar="quux" baz="quuux" />
    </doc>