genshi.template

Implementation of the template engine.

genshi.template.base

Basic templating functionality.

class genshi.template.base.Context(**data)

Container for template input data.

A context provides a stack of scopes (represented by dictionaries).

Template directives such as loops can push a new scope on the stack with data that should only be available inside the loop. When the loop terminates, that scope can get popped off the stack again.

>>> ctxt = Context(one='foo', other=1)
>>> ctxt.get('one')
'foo'
>>> ctxt.get('other')
1
>>> ctxt.push(dict(one='frost'))
>>> ctxt.get('one')
'frost'
>>> ctxt.get('other')
1
>>> ctxt.pop()
{'one': 'frost'}
>>> ctxt.get('one')
'foo'
get(key, default=None)

Get a variable’s value, starting at the current scope and going upward.

Parameters:
  • key – the name of the variable
  • default – the default value to return when the variable is not found
has_key(key)

Return whether a variable exists in any of the scopes.

Parameters:key – the name of the variable
items()

Return a list of (name, value) tuples for all variables in the context.

Returns:a list of variables
keys()

Return the name of all variables in the context.

Returns:a list of variable names
pop()

Pop the top-most scope from the stack.

push(data)

Push a new scope on the stack.

Parameters:data – the data dictionary to push on the context stack.
update(mapping)

Update the context from the mapping provided.

class genshi.template.base.DirectiveFactory

Base for classes that provide a set of template directives.

Since:version 0.6
get_directive(name)

Return the directive class for the given name.

Parameters:name – the directive name as used in the template
Returns:the directive class
See:Directive
get_directive_index(dir_cls)

Return a key for the given directive class that should be used to sort it among other directives on the same SUB event.

The default implementation simply returns the index of the directive in the directives list.

Parameters:dir_cls – the directive class
Returns:the sort key
class genshi.template.base.Template(source, filepath=None, filename=None, loader=None, encoding=None, lookup='strict', allow_exec=True)

Abstract template base class.

This class implements most of the template processing model, but does not specify the syntax of templates.

generate(*args, **kwargs)

Apply the template to the given context data.

Any keyword arguments are made available to the template as context data.

Only one positional argument is accepted: if it is provided, it must be an instance of the Context class, and keyword arguments are ignored. This calling style is used for internal processing.

Returns:a markup event stream representing the result of applying the template to the context data.
exception genshi.template.base.TemplateError(message, filename=None, lineno=-1, offset=-1)

Base exception class for errors related to template processing.

exception genshi.template.base.TemplateRuntimeError(message, filename=None, lineno=-1, offset=-1)

Exception raised when an the evaluation of a Python expression in a template causes an error.

exception genshi.template.base.TemplateSyntaxError(message, filename=None, lineno=-1, offset=-1)

Exception raised when an expression in a template causes a Python syntax error, or the template is not well-formed.

exception genshi.template.base.BadDirectiveError(name, filename=None, lineno=-1)

Exception raised when an unknown directive is encountered when parsing a template.

An unknown directive is any attribute using the namespace for directives, with a local name that doesn’t match any registered directive.

genshi.template.directives

Implementation of the various template directives.

class genshi.template.directives.AttrsDirective(value, template=None, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:attrs template directive.

The value of the py:attrs attribute should be a dictionary or a sequence of (name, value) tuples. The items in that dictionary or sequence are added as attributes to the element:

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<ul xmlns:py="http://genshi.edgewall.org/">
...   <li py:attrs="foo">Bar</li>
... </ul>''')
>>> print(tmpl.generate(foo={'class': 'collapse'}))
<ul>
  <li class="collapse">Bar</li>
</ul>
>>> print(tmpl.generate(foo=[('class', 'collapse')]))
<ul>
  <li class="collapse">Bar</li>
</ul>

If the value evaluates to None (or any other non-truth value), no attributes are added:

>>> print(tmpl.generate(foo=None))
<ul>
  <li>Bar</li>
</ul>
class genshi.template.directives.ChooseDirective(value, template=None, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:choose directive for conditionally selecting one of several body elements to display.

If the py:choose expression is empty the expressions of nested py:when directives are tested for truth. The first true py:when body is output. If no py:when directive is matched then the fallback directive py:otherwise will be used.

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"
...   py:choose="">
...   <span py:when="0 == 1">0</span>
...   <span py:when="1 == 1">1</span>
...   <span py:otherwise="">2</span>
... </div>''')
>>> print(tmpl.generate())
<div>
  <span>1</span>
</div>

If the py:choose directive contains an expression, the nested py:when directives are tested for equality to the py:choose expression:

>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/"
...   py:choose="2">
...   <span py:when="1">1</span>
...   <span py:when="2">2</span>
... </div>''')
>>> print(tmpl.generate())
<div>
  <span>2</span>
</div>

Behavior is undefined if a py:choose block contains content outside a py:when or py:otherwise block. Behavior is also undefined if a py:otherwise occurs before py:when blocks.

class genshi.template.directives.ContentDirective(value, template=None, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:content template directive.

This directive replaces the content of the element with the result of evaluating the value of the py:content attribute:

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<ul xmlns:py="http://genshi.edgewall.org/">
...   <li py:content="bar">Hello</li>
... </ul>''')
>>> print(tmpl.generate(bar='Bye'))
<ul>
  <li>Bye</li>
</ul>
class genshi.template.directives.DefDirective(args, template, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:def template directive.

This directive can be used to create “Named Template Functions”, which are template snippets that are not actually output during normal processing, but rather can be expanded from expressions in other places in the template.

A named template function can be used just like a normal Python function from template expressions:

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
...   <p py:def="echo(greeting, name='world')" class="message">
...     ${greeting}, ${name}!
...   </p>
...   ${echo('Hi', name='you')}
... </div>''')
>>> print(tmpl.generate(bar='Bye'))
<div>
  <p class="message">
    Hi, you!
  </p>
</div>

If a function does not require parameters, the parenthesis can be omitted in the definition:

>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
...   <p py:def="helloworld" class="message">
...     Hello, world!
...   </p>
...   ${helloworld()}
... </div>''')
>>> print(tmpl.generate(bar='Bye'))
<div>
  <p class="message">
    Hello, world!
  </p>
</div>
class genshi.template.directives.ForDirective(value, template, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:for template directive for repeating an element based on an iterable in the context data.

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<ul xmlns:py="http://genshi.edgewall.org/">
...   <li py:for="item in items">${item}</li>
... </ul>''')
>>> print(tmpl.generate(items=[1, 2, 3]))
<ul>
  <li>1</li><li>2</li><li>3</li>
</ul>
class genshi.template.directives.IfDirective(value, template=None, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:if template directive for conditionally excluding elements from being output.

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
...   <b py:if="foo">${bar}</b>
... </div>''')
>>> print(tmpl.generate(foo=True, bar='Hello'))
<div>
  <b>Hello</b>
</div>
class genshi.template.directives.MatchDirective(value, template, hints=None, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:match template directive.

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
...   <span py:match="greeting">
...     Hello ${select('@name')}
...   </span>
...   <greeting name="Dude" />
... </div>''')
>>> print(tmpl.generate())
<div>
  <span>
    Hello Dude
  </span>
</div>
class genshi.template.directives.OtherwiseDirective(value, template, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:otherwise directive for nesting in a parent with the py:choose directive.

See the documentation of ChooseDirective for usage.

class genshi.template.directives.ReplaceDirective(value, template=None, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:replace template directive.

This directive replaces the element with the result of evaluating the value of the py:replace attribute:

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
...   <span py:replace="bar">Hello</span>
... </div>''')
>>> print(tmpl.generate(bar='Bye'))
<div>
  Bye
</div>

This directive is equivalent to py:content combined with py:strip, providing a less verbose way to achieve the same effect:

>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
...   <span py:content="bar" py:strip="">Hello</span>
... </div>''')
>>> print(tmpl.generate(bar='Bye'))
<div>
  Bye
</div>
class genshi.template.directives.StripDirective(value, template=None, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:strip template directive.

When the value of the py:strip attribute evaluates to True, the element is stripped from the output

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
...   <div py:strip="True"><b>foo</b></div>
... </div>''')
>>> print(tmpl.generate())
<div>
  <b>foo</b>
</div>

Leaving the attribute value empty is equivalent to a truth value.

This directive is particulary interesting for named template functions or match templates that do not generate a top-level element:

>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
...   <div py:def="echo(what)" py:strip="">
...     <b>${what}</b>
...   </div>
...   ${echo('foo')}
... </div>''')
>>> print(tmpl.generate())
<div>
    <b>foo</b>
</div>
class genshi.template.directives.WhenDirective(value, template, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:when directive for nesting in a parent with the py:choose directive.

See the documentation of the ChooseDirective for usage.

class genshi.template.directives.WithDirective(value, template, namespaces=None, lineno=-1, offset=-1)

Implementation of the py:with template directive, which allows shorthand access to variables and expressions.

>>> from genshi.template import MarkupTemplate
>>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
...   <span py:with="y=7; z=x+10">$x $y $z</span>
... </div>''')
>>> print(tmpl.generate(x=42))
<div>
  <span>42 7 52</span>
</div>

genshi.template.eval

Support for “safe” evaluation of Python expressions.

class genshi.template.eval.Code(source, filename=None, lineno=-1, lookup='strict', xform=None)

Abstract base class for the Expression and Suite classes.

class genshi.template.eval.Expression(source, filename=None, lineno=-1, lookup='strict', xform=None)

Evaluates Python expressions used in templates.

>>> data = dict(test='Foo', items=[1, 2, 3], dict={'some': 'thing'})
>>> Expression('test').evaluate(data)
'Foo'
>>> Expression('items[0]').evaluate(data)
1
>>> Expression('items[-1]').evaluate(data)
3
>>> Expression('dict["some"]').evaluate(data)
'thing'

Similar to e.g. Javascript, expressions in templates can use the dot notation for attribute access to access items in mappings:

>>> Expression('dict.some').evaluate(data)
'thing'

This also works the other way around: item access can be used to access any object attribute:

>>> class MyClass(object):
...     myattr = 'Bar'
>>> data = dict(mine=MyClass(), key='myattr')
>>> Expression('mine.myattr').evaluate(data)
'Bar'
>>> Expression('mine["myattr"]').evaluate(data)
'Bar'
>>> Expression('mine[key]').evaluate(data)
'Bar'

All of the standard Python operators are available to template expressions. Built-in functions such as len() are also available in template expressions:

>>> data = dict(items=[1, 2, 3])
>>> Expression('len(items)').evaluate(data)
3
evaluate(data)

Evaluate the expression against the given data dictionary.

Parameters:data – a mapping containing the data to evaluate against
Returns:the result of the evaluation
class genshi.template.eval.Suite(source, filename=None, lineno=-1, lookup='strict', xform=None)

Executes Python statements used in templates.

>>> data = dict(test='Foo', items=[1, 2, 3], dict={'some': 'thing'})
>>> Suite("foo = dict['some']").execute(data)
>>> data['foo']
'thing'
execute(data)

Execute the suite in the given data dictionary.

Parameters:data – a mapping containing the data to execute in
class genshi.template.eval.LenientLookup

Default variable lookup mechanism for expressions.

When an undefined variable is referenced using this lookup style, the reference evaluates to an instance of the Undefined class:

>>> expr = Expression('nothing', lookup='lenient')
>>> undef = expr.evaluate({})
>>> undef
<Undefined 'nothing'>

The same will happen when a non-existing attribute or item is accessed on an existing object:

>>> expr = Expression('something.nil', lookup='lenient')
>>> expr.evaluate({'something': dict()})
<Undefined 'nil'>

See the documentation of the Undefined class for details on the behavior of such objects.

See:StrictLookup
classmethod undefined(key, owner=<object object>)

Return an Undefined object.

class genshi.template.eval.StrictLookup

Strict variable lookup mechanism for expressions.

Referencing an undefined variable using this lookup style will immediately raise an UndefinedError:

>>> expr = Expression('nothing', lookup='strict')
>>> try:
...     expr.evaluate({})
... except UndefinedError, e:
...     print e.msg
"nothing" not defined

The same happens when a non-existing attribute or item is accessed on an existing object:

>>> expr = Expression('something.nil', lookup='strict')
>>> try:
...     expr.evaluate({'something': dict()})
... except UndefinedError, e:
...     print e.msg
{} has no member named "nil"
classmethod undefined(key, owner=<object object>)

Raise an UndefinedError immediately.

class genshi.template.eval.Undefined(name, owner=<object object>)

Represents a reference to an undefined variable.

Unlike the Python runtime, template expressions can refer to an undefined variable without causing a NameError to be raised. The result will be an instance of the Undefined class, which is treated the same as False in conditions, but raise an exception on any other operation:

>>> foo = Undefined('foo')
>>> bool(foo)
False
>>> list(foo)
[]
>>> print(foo)
undefined

However, calling an undefined variable, or trying to access an attribute of that variable, will raise an exception that includes the name used to reference that undefined variable.

>>> try:
...     foo('bar')
... except UndefinedError, e:
...     print e.msg
"foo" not defined
>>> try:
...     foo.bar
... except UndefinedError, e:
...     print e.msg
"foo" not defined
See:LenientLookup
exception genshi.template.eval.UndefinedError(name, owner=<object object>)

Exception thrown when a template expression attempts to access a variable not defined in the context.

See:LenientLookup, StrictLookup

genshi.template.interpolation

String interpolation routines, i.e. the splitting up a given text into some parts that are literal strings, and others that are Python expressions.

genshi.template.interpolation.interpolate(text, filepath=None, lineno=-1, offset=0, lookup='strict')

Parse the given string and extract expressions.

This function is a generator that yields TEXT events for literal strings, and EXPR events for expressions, depending on the results of parsing the string.

>>> for kind, data, pos in interpolate("hey ${foo}bar"):
...     print('%s %r' % (kind, data))
TEXT 'hey '
EXPR Expression('foo')
TEXT 'bar'
Parameters:
  • text – the text to parse
  • filepath – absolute path to the file in which the text was found (optional)
  • lineno – the line number at which the text was found (optional)
  • offset – the column number at which the text starts in the source (optional)
  • lookup – the variable lookup mechanism; either “lenient” (the default), “strict”, or a custom lookup class
Returns:

a list of TEXT and EXPR events

Raises TemplateSyntaxError:
 

when a syntax error in an expression is encountered

genshi.template.loader

Template loading and caching.

class genshi.template.loader.TemplateLoader(search_path=None, auto_reload=False, default_encoding=None, max_cache_size=25, default_class=None, variable_lookup='strict', allow_exec=True, callback=None)

Responsible for loading templates from files on the specified search path.

>>> import tempfile
>>> fd, path = tempfile.mkstemp(suffix='.html', prefix='template')
>>> os.write(fd, u'<p>$var</p>'.encode('utf-8'))
11
>>> os.close(fd)

The template loader accepts a list of directory paths that are then used when searching for template files, in the given order:

>>> loader = TemplateLoader([os.path.dirname(path)])

The load() method first checks the template cache whether the requested template has already been loaded. If not, it attempts to locate the template file, and returns the corresponding Template object:

>>> from genshi.template import MarkupTemplate
>>> template = loader.load(os.path.basename(path))
>>> isinstance(template, MarkupTemplate)
True

Template instances are cached: requesting a template with the same name results in the same instance being returned:

>>> loader.load(os.path.basename(path)) is template
True

The auto_reload option can be used to control whether a template should be automatically reloaded when the file it was loaded from has been changed. Disable this automatic reloading to improve performance.

>>> os.remove(path)
static directory(path)

Loader factory for loading templates from a local directory.

Parameters:path – the path to the local directory containing the templates
Returns:the loader function to load templates from the given directory
Return type:function
load(filename, relative_to=None, cls=None, encoding=None)

Load the template with the given name.

If the filename parameter is relative, this method searches the search path trying to locate a template matching the given name. If the file name is an absolute path, the search path is ignored.

If the requested template is not found, a TemplateNotFound exception is raised. Otherwise, a Template object is returned that represents the parsed template.

Template instances are cached to avoid having to parse the same template file more than once. Thus, subsequent calls of this method with the same template file name will return the same Template object (unless the auto_reload option is enabled and the file was changed since the last parse.)

If the relative_to parameter is provided, the filename is interpreted as being relative to that path.

Parameters:
  • filename – the relative path of the template file to load
  • relative_to – the filename of the template from which the new template is being loaded, or None if the template is being loaded directly
  • cls – the class of the template object to instantiate
  • encoding – the encoding of the template to load; defaults to the default_encoding of the loader instance
Returns:

the loaded Template instance

Raises TemplateNotFound:
 

if a template with the given name could not be found

static package(name, path)

Loader factory for loading templates from egg package data.

Parameters:
  • name – the name of the package containing the resources
  • path – the path inside the package data
Returns:

the loader function to load templates from the given package

Return type:

function

static prefixed(**delegates)

Factory for a load function that delegates to other loaders depending on the prefix of the requested template path.

The prefix is stripped from the filename when passing on the load request to the delegate.

>>> load = prefixed(
...     app1 = lambda filename: ('app1', filename, None, None),
...     app2 = lambda filename: ('app2', filename, None, None)
... )
>>> print(load('app1/foo.html'))
('app1', 'app1/foo.html', None, None)
>>> print(load('app2/bar.html'))
('app2', 'app2/bar.html', None, None)
Parameters:delegates – mapping of path prefixes to loader functions
Returns:the loader function
Return type:function
exception genshi.template.loader.TemplateNotFound(name, search_path)

Exception raised when a specific template file could not be found.

genshi.template.loader.directory(path)

Loader factory for loading templates from a local directory.

Parameters:path – the path to the local directory containing the templates
Returns:the loader function to load templates from the given directory
Return type:function
genshi.template.loader.package(name, path)

Loader factory for loading templates from egg package data.

Parameters:
  • name – the name of the package containing the resources
  • path – the path inside the package data
Returns:

the loader function to load templates from the given package

Return type:

function

genshi.template.loader.prefixed(**delegates)

Factory for a load function that delegates to other loaders depending on the prefix of the requested template path.

The prefix is stripped from the filename when passing on the load request to the delegate.

>>> load = prefixed(
...     app1 = lambda filename: ('app1', filename, None, None),
...     app2 = lambda filename: ('app2', filename, None, None)
... )
>>> print(load('app1/foo.html'))
('app1', 'app1/foo.html', None, None)
>>> print(load('app2/bar.html'))
('app2', 'app2/bar.html', None, None)
Parameters:delegates – mapping of path prefixes to loader functions
Returns:the loader function
Return type:function

genshi.template.markup

Markup templating engine.

class genshi.template.markup.MarkupTemplate(source, filepath=None, filename=None, loader=None, encoding=None, lookup='strict', allow_exec=True)

Implementation of the template language for XML-based templates.

>>> tmpl = MarkupTemplate('''<ul xmlns:py="http://genshi.edgewall.org/">
...   <li py:for="item in items">${item}</li>
... </ul>''')
>>> print(tmpl.generate(items=[1, 2, 3]))
<ul>
  <li>1</li><li>2</li><li>3</li>
</ul>
add_directives(namespace, factory)

Register a custom DirectiveFactory for a given namespace.

Parameters:
  • namespace (basestring) – the namespace URI
  • factory (DirectiveFactory) – the directive factory to register
Since:

version 0.6

genshi.template.plugin

Basic support for the template engine plugin API used by TurboGears and CherryPy/Buffet.

exception genshi.template.plugin.ConfigurationError

Exception raised when invalid plugin options are encountered.

class genshi.template.plugin.AbstractTemplateEnginePlugin(extra_vars_func=None, options=None)

Implementation of the plugin API.

load_template(templatename, template_string=None)

Find a template specified in python ‘dot’ notation, or load one from a string.

render(info, format=None, fragment=False, template=None)

Render the template to a string using the provided info.

transform(info, template)

Render the output to an event stream.

class genshi.template.plugin.MarkupTemplateEnginePlugin(extra_vars_func=None, options=None)

Implementation of the plugin API for markup templates.

template_class

alias of MarkupTemplate

transform(info, template)

Render the output to an event stream.

class genshi.template.plugin.TextTemplateEnginePlugin(extra_vars_func=None, options=None)

Implementation of the plugin API for text templates.

template_class

alias of OldTextTemplate

genshi.template.text

Plain text templating engine.

This module implements two template language syntaxes, at least for a certain transitional period. OldTextTemplate (aliased to just TextTemplate) defines a syntax that was inspired by Cheetah/Velocity. NewTextTemplate on the other hand is inspired by the syntax of the Django template language, which has more explicit delimiting of directives, and is more flexible with regards to white space and line breaks.

In a future release, OldTextTemplate will be phased out in favor of NewTextTemplate, as the names imply. Therefore the new syntax is strongly recommended for new projects, and existing projects may want to migrate to the new syntax to remain compatible with future Genshi releases.

class genshi.template.text.NewTextTemplate(source, filepath=None, filename=None, loader=None, encoding=None, lookup='strict', allow_exec=False, delims=('{%', '%}', '{#', '#}'))

Implementation of a simple text-based template engine. This class will replace OldTextTemplate in a future release.

It uses a more explicit delimiting style for directives: instead of the old style which required putting directives on separate lines that were prefixed with a # sign, directives and commenbtsr are enclosed in delimiter pairs (by default {% ... %} and {# ... #}, respectively).

Variable substitution uses the same interpolation syntax as for markup languages: simple references are prefixed with a dollar sign, more complex expression enclosed in curly braces.

>>> tmpl = NewTextTemplate('''Dear $name,
... 
... {# This is a comment #}
... We have the following items for you:
... {% for item in items %}
...  * ${'Item %d' % item}
... {% end %}
... ''')
>>> print(tmpl.generate(name='Joe', items=[1, 2, 3]).render(encoding=None))
Dear Joe,


We have the following items for you:

 * Item 1

 * Item 2

 * Item 3

By default, no spaces or line breaks are removed. If a line break should not be included in the output, prefix it with a backslash:

>>> tmpl = NewTextTemplate('''Dear $name,
... 
... {# This is a comment #}\
... We have the following items for you:
... {% for item in items %}\
...  * $item
... {% end %}\
... ''')
>>> print(tmpl.generate(name='Joe', items=[1, 2, 3]).render(encoding=None))
Dear Joe,

We have the following items for you:
 * 1
 * 2
 * 3

Backslashes are also used to escape the start delimiter of directives and comments:

>>> tmpl = NewTextTemplate('''Dear $name,
... 
... \{# This is a comment #}
... We have the following items for you:
... {% for item in items %}\
...  * $item
... {% end %}\
... ''')
>>> print(tmpl.generate(name='Joe', items=[1, 2, 3]).render(encoding=None))
Dear Joe,

{# This is a comment #}
We have the following items for you:
 * 1
 * 2
 * 3
Since:version 0.5
class genshi.template.text.OldTextTemplate(source, filepath=None, filename=None, loader=None, encoding=None, lookup='strict', allow_exec=True)

Legacy implementation of the old syntax text-based templates. This class is provided in a transition phase for backwards compatibility. New code should use the NewTextTemplate class and the improved syntax it provides.

>>> tmpl = OldTextTemplate('''Dear $name,
... 
... We have the following items for you:
... #for item in items
...  * $item
... #end
... 
... All the best,
... Foobar''')
>>> print(tmpl.generate(name='Joe', items=[1, 2, 3]).render(encoding=None))
Dear Joe,

We have the following items for you:
 * 1
 * 2
 * 3

All the best,
Foobar
genshi.template.text.TextTemplate

alias of OldTextTemplate