zope.tales

Latest release Supported Python versions https://travis-ci.org/zopefoundation/zope.tales.svg?branch=master https://coveralls.io/repos/github/zopefoundation/zope.tales/badge.svg?branch=master Documentation Status

zope.tales (Template Attribute Language - Expression Syntax) is an expression language designed to work with zope.tal (although it can be used independently). The two are integrated to produce page templates in zope.pagetemplate.

The specification for TAL and TALES can be found at http://docs.zope.org/zope2/zope2book/AppendixC.html

Documentation on this implementation and its API can be found at https://zopetales.readthedocs.io/

API Documentation:

Interfaces

Interface that describes the TALES implementation.

interface zope.tales.interfaces.ITALESFunctionNamespace[source]

Function namespaces can be used in TALES path expressions to extract information in non-default ways.

setEngine(engine)

Sets the engine that is used to evaluate TALES expressions.

interface zope.tales.interfaces.ITALESExpression[source]

TALES expression

These are expression handlers that handle a specific type of expression in TALES, e.g. path or string expression.

__call__(econtext)

Evaluate expression according to the given execution context econtext and return computed value.

interface zope.tales.interfaces.ITALESIterator[source]

Extends: zope.tal.interfaces.ITALIterator

TAL Iterator provided by TALES.

Values of this iterator are assigned to items in the repeat namespace.

For example, with a TAL statement like: tal:repeat="item items", an iterator will be assigned to repeat/item (using a path expression). The iterator provides a number of handy methods useful in writing TAL loops.

The results are undefined of calling any of the methods except length before the first iteration.

index()

Return the position (starting with “0”) within the iteration

number()

Return the position (starting with “1”) within the iteration

even()

Return whether the current position is even.

odd()

Return whether the current position is odd

parity()

Return ‘odd’ or ‘even’ depending on the position’s parity

Useful for assigning CSS class names to table rows.

start()

Return whether the current position is the first position

end()

Return whether the current position is the last position

letter()

Return the position (starting with “a”) within the iteration

Letter()

Return the position (starting with “A”) within the iteration

roman()

Return the position (starting with “i”) within the iteration

Roman()

Return the position (starting with “I”) within the iteration

item()

Return the item at the current position

length()

Return the length of the sequence

Note that this may fail if the TAL iterator was created on a Python iterator.

Expression Implementations

Basic Page Template expression types.

Expression objects are created by the ExpressionEngine (they must have previously been registered with registerType()). The expression object itself is a callable object taking one argument, econtext, which is the local expression namespace.

zope.tales.expressions.simpleTraverse(object, path_items, econtext)[source]

Traverses a sequence of names, first trying attributes then items.

class zope.tales.expressions.SubPathExpr(path, traverser, engine)[source]

Bases: object

Implementation of a single path expression.

class zope.tales.expressions.PathExpr(name, expr, engine, traverser=<function simpleTraverse>)[source]

Bases: object

One or more subpath expressions, separated by |.

class zope.tales.expressions.StringExpr(name, expr, engine)[source]

Bases: object

An expression that produces a string.

Sub-sequences of the string that begin with $ are interpreted as path expressions to evaluate.

class zope.tales.expressions.NotExpr(name, expr, engine)[source]

Bases: object

An expression that negates the boolean value of its sub-expression.

class zope.tales.expressions.DeferExpr(name, expr, compiler)[source]

Bases: object

An expression that will defer evaluation of the sub-expression until necessary, preserving the execution context it was created with.

This is useful in tal:define expressions:

<div tal:define="thing defer:some/path">
  ...
  <!-- some/path is only evaluated if condition is true -->
  <span tal:condition="condition" tal:content="thing"/>
</div>
class zope.tales.expressions.LazyWrapper(expr, econtext)[source]

Bases: zope.tales.expressions.DeferWrapper

Wrapper for lazy: expression

class zope.tales.expressions.LazyExpr(name, expr, compiler)[source]

Bases: zope.tales.expressions.DeferExpr

An expression that will defer evaluation of its sub-expression until the first time it is necessary.

This is like DeferExpr, but caches the result of evaluating the expression.

class zope.tales.expressions.SimpleModuleImporter[source]

Bases: object

Minimal module importer with no security.

class zope.tales.pythonexpr.PythonExpr(name, expr, engine)[source]

Bases: object

Evaluates a python expression by calling eval() after compiling it with compile().

Parameters:
  • expr (str) – The Python expression.
  • engine (ExpressionEngine) – The expression compiler that is creating us.

Expression Compiler

class zope.tales.tales.ExpressionEngine[source]

Bases: object

Expression compiler, an implementation of zope.tal.interfaces.ITALExpressionCompiler.

An instance of this class keeps a mutable collection of expression type handlers. It can compile expression strings by delegating to these handlers. It can provide an expression engine, which is capable of holding state and evaluating compiled expressions.

By default, this object does not know how to compile any expression types. See zope.tales.engine.Engine and zope.tales.engine.DefaultEngine() for pre-configured instances supporting the standard expression types.

registerFunctionNamespace(namespacename, namespacecallable)[source]

Register a function namespace

Parameters:
  • namespace (str) – a string containing the name of the namespace to be registered
  • namespacecallable (callable) –

    a callable object which takes the following parameter:

    context:the object on which the functions provided by this namespace will be called

    This callable should return an object which can be traversed to get the functions provided by the this namespace.

For example:

class stringFuncs(object):

   def __init__(self,context):
      self.context = str(context)

   def upper(self):
      return self.context.upper()

   def lower(self):
      return self.context.lower()

 engine.registerFunctionNamespace('string', stringFuncs)
getFunctionNamespace(namespacename)[source]

Returns the function namespace

registerType(name, handler)[source]

Register an expression of name to be handled with handler.

Raises:RegistrationError – If this is a duplicate registration for name, or if name is not a valid expression type name.
getContext(contexts=None, **kwcontexts)[source]

Return a new expression engine.

The keyword arguments passed in kwcantexts become the default variable context for the returned engine. If contexts is given, it should be a mapping, and the values it contains will override the keyword arguments.

Return type:Context
zope.tales.engine.DefaultEngine()[source]

Create and return an instance of ExpressionEngine (an implementation of zope.tal.interfaces.ITALExpressionCompiler) with the following expression types registered:

string
StringExpr
python
PythonExpr
not
NotExpr
defer
DeferExpr
lazy
LazyExpr
modules
SimpleModuleImporter

In addition, the default path expressions (standard, path, exists and nocall), all implemented by PathExpr, are registered.

zope.tales.engine.Engine

An instance of the default engine (DefaultEngine()) that can be used for simple shared cases

Expression Engine

class zope.tales.tales.Context(engine, contexts)[source]

Bases: object

Expression engine, an implementation of zope.tal.interfaces.ITALExpressionEngine.

This class is called Context because an instance of this class holds context information (namespaces) that it uses when evaluating compiled expressions.

Parameters:
setContext(name, value)[source]

Hook to allow subclasses to do things like adding security proxies.

evaluate(expression)[source]

Evaluate the expression by calling it, passing in this object, and return the raw results.

If expression is a string, it is first compiled.

evaluateValue(expression)

Evaluate the expression by calling it, passing in this object, and return the raw results.

If expression is a string, it is first compiled.

evaluateBoolean(expr)[source]

Evaluate the expression and return the boolean value of its result.

evaluateStructure(expression)

Evaluate the expression by calling it, passing in this object, and return the raw results.

If expression is a string, it is first compiled.

evaluateMacro(expression)

Evaluate the expression by calling it, passing in this object, and return the raw results.

If expression is a string, it is first compiled.

Exceptions

A number of exceptions are defined.

class zope.tales.tales.TALESError[source]

Bases: exceptions.Exception

Error during TALES evaluation

class zope.tales.tales.Undefined[source]

Bases: zope.tales.tales.TALESError

Exception raised on traversal of an undefined path

class zope.tales.tales.CompilerError[source]

Bases: exceptions.Exception

TALES Compiler Error

class zope.tales.tales.RegistrationError[source]

Bases: exceptions.Exception

Expression type or base name registration Error

Other Objects

class zope.tales.tales.Iterator(name, seq, context)[source]

Bases: object

TALES Iterator.

Default implementation of zope.tales.interfaces.ITALESIterator.

Construct an iterator

Iterators are defined for a name, a sequence, or an iterator and a context, where a context simply has a setLocal method:

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)

A local variable is not set until the iterator is used:

>>> int("foo" in context.vars)
0

We can create an iterator on an empty sequence:

>>> it = Iterator('foo', (), context)

An iterator works as well:

>>> it = Iterator('foo', {"apple":1, "pear":1, "orange":1}, context)
>>> it.next()
True
>>> it = Iterator('foo', {}, context)
>>> it.next()
False
>>> it = Iterator('foo', iter((1, 2, 3)), context)
>>> it.next()
True
>>> it.next()
True
next()

Advance the iterator, if possible.

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> bool(it.next())
True
>>> context.vars['foo']
'apple'
>>> bool(it.next())
True
>>> context.vars['foo']
'pear'
>>> bool(it.next())
True
>>> context.vars['foo']
'orange'
>>> bool(it.next())
False
>>> it = Iterator('foo', {"apple":1, "pear":1, "orange":1}, context)
>>> bool(it.next())
True
>>> bool(it.next())
True
>>> bool(it.next())
True
>>> bool(it.next())
False
>>> it = Iterator('foo', (), context)
>>> bool(it.next())
False
>>> it = Iterator('foo', {}, context)
>>> bool(it.next())
False

If we can advance, set a local variable to the new value.

index()[source]

Get the iterator index

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.index()
Traceback (most recent call last):
...
TypeError: No iteration position
>>> int(bool(it.next()))
1
>>> it.index()
0
>>> int(bool(it.next()))
1
>>> it.index()
1
>>> int(bool(it.next()))
1
>>> it.index()
2
number()[source]

Get the iterator position

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> int(bool(it.next()))
1
>>> it.number()
1
>>> int(bool(it.next()))
1
>>> it.number()
2
>>> int(bool(it.next()))
1
>>> it.number()
3
even()[source]

Test whether the position is even

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.next()
True
>>> it.even()
True
>>> it.next()
True
>>> it.even()
False
>>> it.next()
True
>>> it.even()
True
odd()[source]

Test whether the position is odd

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.next()
True
>>> it.odd()
False
>>> it.next()
True
>>> it.odd()
True
>>> it.next()
True
>>> it.odd()
False
parity()[source]

Return ‘odd’ or ‘even’ depending on the position’s parity

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.next()
True
>>> it.parity()
'odd'
>>> it.next()
True
>>> it.parity()
'even'
>>> it.next()
True
>>> it.parity()
'odd'
letter(base=97, radix=26)[source]

Get the iterator position as a lower-case letter

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.letter()
Traceback (most recent call last):
...
TypeError: No iteration position
>>> it.next()
True
>>> it.letter()
'a'
>>> it.next()
True
>>> it.letter()
'b'
>>> it.next()
True
>>> it.letter()
'c'
Letter()[source]

Get the iterator position as an upper-case letter

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.next()
True
>>> it.Letter()
'A'
>>> it.next()
True
>>> it.Letter()
'B'
>>> it.next()
True
>>> it.Letter()
'C'
Roman(rnvalues=((1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')))[source]

Get the iterator position as an upper-case roman numeral

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.next()
True
>>> it.Roman()
'I'
>>> it.next()
True
>>> it.Roman()
'II'
>>> it.next()
True
>>> it.Roman()
'III'
roman()[source]

Get the iterator position as a lower-case roman numeral

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.next()
True
>>> it.roman()
'i'
>>> it.next()
True
>>> it.roman()
'ii'
>>> it.next()
True
>>> it.roman()
'iii'
start()[source]

Test whether the position is the first position

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.next()
True
>>> it.start()
True
>>> it.next()
True
>>> it.start()
False
>>> it.next()
True
>>> it.start()
False
>>> it = Iterator('foo', {}, context)
>>> it.start()
False
>>> it.next()
False
>>> it.start()
False
end()[source]

Test whether the position is the last position

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.next()
True
>>> it.end()
False
>>> it.next()
True
>>> it.end()
False
>>> it.next()
True
>>> it.end()
True
>>> it = Iterator('foo', {}, context)
>>> it.end()
False
>>> it.next()
False
>>> it.end()
False
item()[source]

Get the iterator value

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.item()
Traceback (most recent call last):
...
TypeError: No iteration position
>>> it.next()
True
>>> it.item()
'apple'
>>> it.next()
True
>>> it.item()
'pear'
>>> it.next()
True
>>> it.item()
'orange'
>>> it = Iterator('foo', {1:2}, context)
>>> it.next()
True
>>> it.item()
1
length()[source]

Get the length of the iterator sequence

>>> context = Context(ExpressionEngine(), {})
>>> it = Iterator('foo', ("apple", "pear", "orange"), context)
>>> it.length()
3

You can even get the length of a mapping:

>>> it = Iterator('foo', {"apple":1, "pear":2, "orange":3}, context)
>>> it.length()
3

But you can’t get the length of an iterable which doesn’t support len():

>>> class MyIter(object):
...     def __init__(self, seq):
...         self._iter = iter(seq)
...     def __iter__(self):
...         return self
...     def __next__(self):
...         return next(self._iter)
...     next = __next__
>>> it = Iterator('foo', MyIter({"apple":1, "pear":2}), context)
>>> try:
...     it.length()
... except TypeError:
...     pass
... else:
...     print('Expected TypeError')

Changes

4.2.1 (unreleased)

4.2.0 (2017-09-22)

  • Add support for Python 3.5 and 3.6.
  • Drop support for Python 2.6, 3.2 and 3.3.
  • Drop support for python setup.py test.
  • Reach 100% test coverage and maintain it via tox.ini and Travis CI.

4.1.1 (2015-06-06)

  • Add support for Python 3.2 and PyPy3.

4.1.0 (2014-12-29)

Note

Support for PyPy3 is pending release of a fix for: https://bitbucket.org/pypy/pypy/issue/1946

  • Add support for Python 3.4.
  • Add support for testing on Travis.

4.0.2 (2013-11-12)

  • Add missing six dependency

4.0.1 (2013-02-22)

  • Fix a previously untested Python 3.3 compatibility problem.

4.0.0 (2013-02-14)

  • Remove hard dependency on zope.tal, which was already conditionalized but required via setup.py.
  • Add support for Python 3.3 and PyPy.
  • Replace deprecated zope.interface.implements usage with equivalent zope.interface.implementer decorator.
  • Drop support for Python 2.4 and 2.5.
  • Fix documentation link in README.txt

3.5.2 (2012-05-23)

3.5.1 (2010-04-30)

  • Remove use of zope.testing.doctestunit in favor of stdlib’s ‘doctest.

3.5.0 (2010-01-01)

  • Port the lazy expression from Products.PageTemplates.

3.4.0 (2007-10-03)

  • Update package setup.
  • Initial release outside the Zope 3 trunk.

3.2.0 (2006-01-05)

  • Corresponds to the verison of the zope.tales package shipped as part of the Zope 3.2.0 release.
  • Documentation / test fixes.

3.0.0 (2004-11-07)

  • Corresponds to the verison of the zope.tales package shipped as part of the Zope X3.0.0 release.

Indices and tables