Edgewall Software

genshi.template.directives

Implementation of the various template directives.

DirectiveMeta

Meta class for template directives.

Directive

Abstract base class for template directives.

A directive is basically a callable that takes three positional arguments: ctxt is the template data context, stream is an iterable over the events that the directive applies to, and directives is is a list of other directives on the same stream that need to be applied.

Directives can be "anonymous" or "registered". Registered directives can be applied by the template author using an XML attribute with the corresponding name in the template. Such directives should be subclasses of this base class that can be instantiated with the value of the directive attribute as parameter.

Anonymous directives are simply functions conforming to the protocol described above, and can only be applied programmatically (for example by template filters).

attach(cls, template, stream, value, namespaces, pos)

Called after the template stream has been completely parsed.

param template:the Template object
param stream:the event stream associated with the directive
param value:the argument value for the directive; if the directive was specified as an element, this will be an Attrs instance with all specified attributes, otherwise it will be a unicode object with just the attribute value
param namespaces:
 a mapping of namespace URIs to prefixes
param pos:a (filename, lineno, offset) tuple describing the location where the directive was found in the source

This class method should return a (directive, stream) tuple. If directive is not None, it should be an instance of the Directive class, and gets added to the list of directives applied to the substream at runtime. stream is an event stream that replaces the original stream associated with the directive.

AttrsDirective

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>

ContentDirective

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>

attach(cls, template, stream, value, namespaces, pos)

(Not documented)

DefDirective

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>

attach(cls, template, stream, value, namespaces, pos)

(Not documented)

ForDirective

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>

attach(cls, template, stream, value, namespaces, pos)

(Not documented)

IfDirective

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>

attach(cls, template, stream, value, namespaces, pos)

(Not documented)

MatchDirective

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>

attach(cls, template, stream, value, namespaces, pos)

(Not documented)

ReplaceDirective

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>

attach(cls, template, stream, value, namespaces, pos)

(Not documented)

StripDirective

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>

ChooseDirective

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.

attach(cls, template, stream, value, namespaces, pos)

(Not documented)

WhenDirective

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

See the documentation of the ChooseDirective for usage.

attach(cls, template, stream, value, namespaces, pos)

(Not documented)

OtherwiseDirective

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

See the documentation of ChooseDirective for usage.

WithDirective

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>

attach(cls, template, stream, value, namespaces, pos)

(Not documented)


See Genshi XML Template Language, Genshi Text Template Language, ApiDocs/0.6.x, Documentation

Last modified 9 years ago Last modified on Dec 4, 2015, 3:03:06 AM