step - Simple Template Engine for Python

step is a pure-Python module providing a very simple template engine with minimum syntax. It supports variable expansion, flow control and embedding of Python code.

step.Template(template[, strip])
Create a new template instance; template is a string containing any kind of textual content and a set of directives representing variables, control structures and blocks of Python code (see the supported syntax). The boolean parameter strip enables or disables whitespace stripping in the output and can be overridden by the "strip" option in a template string (see below).

1. Template objects

You can generate different strings from a template by providing a specific namespace.

Template.expand([namespace[, **kw]])
Return the string resulting from the interpretation of the template string and variable substitution; namespace is a dictionary used for variables evaluation; additional keyword arguments are added to namespace.
Template.stream(buffer[, namespace[, encoding[, **kw]]])
Write the string resulting from the expansion of the template to the file-like object buffer; the namespace parameter is a dictionary used for variables evaluation; encoding allows you to specify the encoding of the output stream (default is "utf-8"); additional keyword arguments are added to namespace.

2. Supported syntax

Variables are enclosed in {{}} and follow the same syntax rules as Python variables; e.g.:

This is variable x: {{x}}
This is the third item of my_list: {{my_list[2]}}
This is not a variable: \{\{x\}\}

Flow control expressions are written like regular Python control structures, preceded by the % sign and must be closed by a %end<statement> tag; e.g.:

%if (x > 2):
    x is greater than 2
%else:
    x is {{x}}
%endif

All text between <% and %> is considered Python code; you can use the builtin echo() function to output some text from within Python code blocks; e.g.:

<%
import time
echo("Current timestamp is {}".format(time.time()))
%>
<\% This is not Python code %\>

You can use the special function isdef() to perform some actions only if a name is defined in the template namespace; e.g.:

%if isdef("my_var")
    my_var is {{my_var}}
%endif

The setopt() function allows you to enable options that modify the template output; the only supported option is "strip", which removes leading/trailing whitespace, contiguous whitespace and empty lines and defaults to true; e.g.:

<%setopt("strip", True)%>

A backslash at the end of a line will suppress the newline character.

3. Examples

A simple example generating an HTML document:

import step

template = r"""
<%setopt("strip", False)%>
<html>
  <head>
    <title>{{title}}</title>
  </head>
  <body>
    <h1>My Items</h1>

    <ul>
    %for item in items:
      <li>{{item}}</li>
    %endfor
    </ul>

    %if isdef("info"):
        <p>{{info}}</p>
    %endif

    <footer>
<%
import time
echo("Last refresh: {}\n".format(time.ctime()))
%>
    </footer>
  </body>
</html>
"""

namespace = {"title": "My title",
             "items": ["item 1", "item 2", "item 3"],
             "info": "More interesting information"}

print step.Template(template).expand(namespace)