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)
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).

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.

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)