The Zope Page Template (ZPT) language is actually just a set of XML
attributes that can be applied to markup of an DTD.  These attributes
tell the ZPT interpreter how to process the element.  There are
seven different attributes that you can use to direct the processing
of an XML or HTML file (in order of evaluation): define, condition, repeat,
content, replace, attributes, and omit-tag.  These attributes are
described in section \ref{sec:talattributes}.  For a more complete description,
see the official ZPT documentation at
\url{http://www.zope.org/Documentation/Books/ZopeBook/2_6Edition/ZPT.stx}.


\section{Template Attribute Language Expression Syntax (TALES)}

The Template Attribute Language Expression Syntax (TALES) is used
by the attribute language described in the next section.  The TALES
syntax is used to evaluate expressions based on objects in the
template namespace.  The results of these expressions can be used to
define variables, produce output, or be used as booleans.  There are
also several operators used to modify the behavior or interpretation
of an expression.  The expressions and their modifiers are described
below.

\paragraph{path: operator\label{sec:pathoperator}}

A ``path'' is the most basic form on an expression in ZPT.  The basic form
is shown below.
\begin{verbatim}
[path:]string [ | TALES expression ]
\end{verbatim}

The \var{path:} operator is actually optional on all paths.  Leaving it
off makes no difference.  The ``string'' in the above syntax is a '/'
delimited string of names.  Each name refers to a property of the
previous name in the string.  Properties can include attributes, methods,
or keys in a dictionary.  These properties can in turn have properties
of their own.  Some examples of paths are shown below.
\begin{verbatim}
# Access the parentNode attribute of chapter, then get its title
chapter/parentNode/title

# Get the key named 'foo' from the dictionary bar
bar/foo

# Call the title method on the string in the variable booktitle
booktitle/title
\end{verbatim}

It is possible to specify multiple paths separated by a pipe (|).
These paths are evaluated from left to right.  The first one to return
a non-None value is used.
\begin{verbatim}
# Look for the title on the current chapter node as well as its parents
chapter/title | chapter/parentNode/title | chapter/parentNode/parentNode/title

# Look for the value of the option otherwise get its default value
myoptions/encoding | myoptions/defaultencoding
\end{verbatim}

There are a few keywords that can be used in place of a path in a
TALES expression as well.
\begin{tableii}{l|p{4in}}{var}{Name}{Purpose}
\lineii{nothing}{same as \var{None} in Python}
\lineii{default}{keeps whatever the existing value of the element or attribute is}
\lineii{options}{dictionary of values passed in to the template when instatiated}
\lineii{repeat}{the repeat variable (see \ref{sec:talrepeat})}
\lineii{attrs}{dictonary of the original attributes of the element}
\lineii{CONTEXTS}{dictionary containing all of the above}
\end{tableii}


\paragraph{exists: operator}

This operator returns true if the path exists.  If the path does not exist,
the operator returns false.   The syntax is as follows.
\begin{verbatim}
exists:path
\end{verbatim}

The ``path'' in the code above is a path as described in section
\ref{sec:pathoperator}.  This operator is commonly combined with the
not: operator.


\paragraph{nocall: operator}

By default, if a property that is retrieved is callable, it will be
called automatically.  Using the nocall: operator, prevents this
execution from happening.  The syntax is shown below.
\begin{verbatim}
nocall:path
\end{verbatim}


\paragraph{not: operator}

The not: operator simply negates the boolean result of the path.  If
the path is a boolean true, the not: operator will return false, and
vice versa.  The syntax is shown below.
\begin{verbatim}
not:path
\end{verbatim}


\paragraph{string: operator}

The string: operator allows you to combine literal strings and paths
into one string.  Paths are inserted into the literal string using a
syntax much like that of Python Templates: \$path or \$\{path\}.
The general syntax is:
\begin{verbatim}
string:text
\end{verbatim}

Here are some examples of using the string: operator.
\begin{verbatim}
string:Next - ${section/links/next}
string:($pagenumber)
string:[${figure/number}] ${figure/caption}
\end{verbatim}


\paragraph{python: operator}

The python: operator allows you to evaluate a Python expression.  The
syntax is as follows.
\begin{verbatim}
python:python-code
\end{verbatim}

The ``python-code'' in the expression above can include any of the Python
built-in functions and operators as well as four new functions that
correspond to the TALES operators: path, string, exists, and nocall.
Each of these functions takes a string containing the path to be
evaluated (e.g. path('foo/bar'), exists('chapter/title'), etc.).

When using Python operators, you must escape any characters that would
not be legal in an XML/HTML document (i.e. <>\&).  For example,
to write an expression to test if a number was less than or greater than
two numbers, you would need to do something like the following example.
\begin{verbatim}
# See if the figure number is less than 2 or greater than 4
python: path('figure/number') &lt; 2 or path('figure/number') &gt; 4
\end{verbatim}


\paragraph{stripped: operator}

The stripped: operator only exists in the SimpleTAL distribution provided
by \plasTeX.  It evaluates the given path and removes any markup from
that path.  Essentially, it is a way to get a plain text representation
of the path.  The syntax is as follows.
\begin{verbatim}
stripped:path
\end{verbatim}


\section{Template Attribute Language (TAL) Attributes\label{sec:talattributes}}

\paragraph{tal:define}

The \attr{tal:define} attribute allows you to define a variable for use
later in the template.  Variables can be specifies as local (only for
use in the scope of the current element) or global (for use anywhere in
the template).  The syntax of the define attribute is shown below.
\begin{verbatim}
tal:define="[ local | global ] name expression [; define-expression ]"
\end{verbatim}

The define attributes sets the value of ``name'' to ``expression.''
By default, the scope of the variable is local, but can be specified
as global by including the ``global'' keyword before the name of the
variable.  As shown in the grammar above, you can specify multiple
variables in one \attr{tal:define} attribute by separating the define
expressions by semi-colons.

Examples of using the \attr{tal:define} attribute are shown belaw.
\begin{verbatim}
<p tal:define="global title document/title;
               next self/links/next;
               previous self/links/previous;
               length python:len(self);
               up string:Up - ${self/links/up}">
...
</p>
\end{verbatim}


\paragraph{tal:condition}

The \attr{tal:condition} attribute allows you to conditionally include
an element.  The syntax is shown below.
\begin{verbatim}
tal:condition="expression"
\end{verbatim}

The \attr{tal:condition} attribute is very simple.  If the expression
evaluates to true, the element and its children will be evaluated and
included in the output.  If the expression evaluates to false, the element
and its children will not be evaluated or included in the output.
Valid expressions for the \attr{tal:condition} attribute are the same
as those for the expressions in the \attr{tal:define} attribute.
\begin{verbatim}
<p tal:condition="python:len(self)">
    <b tal:condition="self/caption">Caption for paragraph</b>
    ...
</p>
\end{verbatim}


\paragraph{tal:repeat\label{sec:talrepeat}}

The \attr{tal:repeat} attribute allows you to repeat an element multiple
times; the syntax is shown below.
\begin{verbatim}
tal:repeat="name expression"
\end{verbatim}

When the \attr{tal:repeat} attribute is used on an element, the
result of``expression'' is iterated over, and a new element is generated
for each item in the iteration.  The value of the current item is
set to ``name'' much like in the \attr{tal:define} attribute.

Within the scope of the repeated element, another variable is available:
\var{repeat}.  This variable contains several properties related to
the loop.
\begin{tableii}{l|p{4in}}{var}{Name}{Purpose}
\lineii{index}{number of the current iteration starting from zero}
\lineii{number}{number of the current iteration starting from one}
\lineii{even}{is true if the iteration number is even}
\lineii{odd}{is true if the iteration number is odd}
\lineii{start}{is true if this is the first iteration}
\lineii{end}{is true if this is the last iteration; This is never
    true if the repeat expression returns an iterator}
\lineii{length}{the length of the sequence being iterated over; This
    is set to \var{sys.maxint} for iterators.}
\lineii{letter}{lower case letter corresponding to the current iteration
    number starting with 'a'}
\lineii{Letter}{upper case letter corresponding to the current iteration
    number starting with 'A'}
\lineii{roman}{lower case Roman numeral corresponding to the current iteration
    number starting with 'i'}
\lineii{Roman}{upper case Roman numeral corresponding to the current iteration
    number starting with 'I'}
\end{tableii}

To access the properties listed above, you must use the property of
the \var{repeat} variable that corresponds to the repeat variable name.
For example, if your repeat variable name is ``item'', you would access
the above variables using the expressions \var{repeat/item/index},
\var{repeat/item/number}, \var{repeat/item/even}, etc.

A simple example of the \attr{tal:repeat} attribute is shown below.
\begin{verbatim}
<ol>
<li tal:repeat="option options" tal:content="option/name">option name</li>
</ol>
\end{verbatim}

One commonly used feature of rendering tables is alternating row colors.
This is a little bit tricky with ZPT since the \attr{tal:condition}
attribute is evaluated before the \attr{tal:repeat} directive.  You
can get around this by using the \namespace{metal} namespace.  This
is the namespace used by ZPT's macro language\footnote{The macro language
isn't discussed here.  See the official ZPT documentation for more
information.}  You can create another element around the element you
want to be conditional.  This wrapper element is simply there to do the
iterating, but is not included in the output.  The example below shows
how to do alternating row colors in an HTML table.
\begin{verbatim}
<table>
<metal:block tal:repeat="employee employees">
<!-- even rows -->
<tr tal:condition="repeat/employee/even" style="background-color: white">
    <td tal:content="employee/name"></td>
    <td tal:content="employee/title"></td>
</tr>
<!-- odd rows -->
<tr tal:condition="repeat/employee/odd" style="background-color: gray">
    <td tal:content="employee/name"></td>
    <td tal:content="employee/title"></td>
</tr>
</metal:block>
</table>
\end{verbatim}


\paragraph{tal:content}

The \attr{tal:content} attribute evaluates an expression and replaces
the content of the element with the result of the expression.  The
syntax is shown below.
\begin{verbatim}
tal:content="[ text | structure ] expression"
\end{verbatim}

The \var{text} and \var{structure} options in the \attr{tal:content}
attribute indicate whether or not the content returned by the
expression should be escaped (i.e. "\&<> replaced by \&quot;, \&amp;, \&lt;,
and \&gt;, respectively).  When the \var{text} option is used, these
special characters are escaped; this is the default behavior.  When
the \var{structure} option is specified, the result of the expression is
assumed to be valid markup and is not escaped.

In SimpleTAL, the default
behavior is the same as using the \var{text} option.  However, in
\plasTeX, 99.9\% of the time the content returned by the expression is
valid markup, so the default was changed to \var{structure} in the
SimpleTAL package distributed with \plasTeX.


\paragraph{tal:replace}

The \attr{tal:replace} attribute is much like the \attr{tal:content}
attribute.  They both evaluate an expression and include the content
of that expression in the output, and they both have a \var{text} and
\var{structure} option to indicate escaping of special characters.
The difference is that when the \attr{tal:replace} attribute is used,
the element with the \attr{tal:replace} attribute on it is not included
in the output.  Only the content of the evaluated expression is returned.
The syntax of the \attr{tal:replace} attribute is shown below.
\begin{verbatim}
tal:replace="[ text | structure ] expression"
\end{verbatim}


\paragraph{tal:attributes}

The \attr{tal:attributes} attribute allows you to programatically create
attributes on the element.  The syntax is shown below.
\begin{verbatim}
tal:attributes="name expression [; attribute-expression ]"
\end{verbatim}

The syntax of the \attr{tal:attributes} attribute is very similar to
that of the \attr{tal:define} attribute.  However, in the case of the
\attr{tal:attributes} attribute, the name is the name of the attribute
to be created on the element and the expression is evaluated to
get the value of the attribute.  If an error occurs or \var{None} is
returned by the expression, then the attribute is removed from the
element.

Just as in the case of the \attr{tal:define} attribute, you can specify
multiple attributes separated by semi-colons (;).  If a semi-colon character
is needed in the expression, then it must be represented by a double
semi-colon (;;).

An example of using the \attr{tal:attributes} is shown below.
\begin{verbatim}
<a tal:attributes="href self/links/next/url;
                   title self/links/next/title">link text</a>
\end{verbatim}


\paragraph{tal:omit-tag}

The \attr{tal:omit-tag} attribute allows you to conditionally omit an
element.  The syntax is shown below.
\begin{verbatim}
tal:omit-tag="expression"
\end{verbatim}

If the value of ``expression'' evaluates to true (or is empty), the element
is omitted; however, the content of the element is still sent to the output.
If the expression evaluates to false, the element is included in the
output.
