Appendix C: Zope Page Templates Reference ######################################### Zope Page Templates are an HTML/XML generation tool. This appendix is a reference to Zope Page Templates standards: Template Attribute Language (TAL), TAL Expression Syntax (TALES), and Macro Expansion TAL (METAL). It also describes some ZPT-specific behaviors that are not part of the standards. TAL Overview ============ The *Template Attribute Language* (TAL) standard is an attribute language used to create dynamic templates. It allows elements of a document to be replaced, repeated, or omitted. The statements of TAL are XML attributes from the TAL namespace. These attributes can be applied to an XML or HTML document in order to make it act as a template. A **TAL statement** has a name (the attribute name) and a body (the attribute value). For example, a ``content`` statement might look like:: tal:content="string:Hello" The element on which a statement is defined is its **statement element**. Most TAL statements require expressions, but the syntax and semantics of these expressions are not part of TAL. TALES is recommended for this purpose. TAL Namespace +++++++++++++ The TAL namespace URI and recommended alias are currently defined as:: xmlns:tal="http://xml.zope.org/namespaces/tal" This is not a URL, but merely a unique identifier. Do not expect a browser to resolve it successfully. Zope does not require an XML namespace declaration when creating templates with a content-type of ``text/html``. However, it does require an XML namespace declaration for all other content-types. TAL Statements ++++++++++++++ These are the tal statements: - tal:attributes - dynamically change element attributes. - tal:define - define variables. - tal:switch - define a switch condition - tal:condition - test conditions. - tal:case - include element only if expression is equal to parent switch - tal:content - replace the content of an element. - tal:omit-tag - remove an element, leaving the content of the element. - tal:on-error - handle errors. - tal:repeat - repeat an element. - tal:replace - replace the content of an element and remove the element leaving the content. Expressions used in statements may return values of any type, although most statements will only accept strings, or will convert values into a string representation. The expression language must define a value named *nothing* that is not a string. In particular, this value is useful for deleting elements or attributes. Order of Operations +++++++++++++++++++ When there is only one TAL statement per element, the order in which they are executed is simple. Starting with the root element, each element's statements are executed, then each of its child elements is visited, in order, to do the same. Any combination of statements may appear on the same elements, except that the ``content`` and ``replace`` statements may not appear together. Due to the fact that TAL sees statements as XML attributes, even in HTML documents, it cannot use the order in which statements are written in the tag to determine the order in which they are executed. TAL must also forbid multiples of the same kind of statement on a single element, so it is sufficient to arrange the kinds of statement in a precedence list. When an element has multiple statements, they are executed in this order: 1. define 2. switch 3. condition 4. repeat 5. case 6. content or replace 7. attributes 8. omit-tag Since the ``on-error`` statement is only invoked when an error occurs, it does not appear in the list. It may not be apparent that there needs to be an ordering. The reason that there must be one is that TAL is XML based. The XML specification specifically states that XML processors are free to rewrite the terms. In particular, you cannot assume that attributes of an XML statement will be processed in the order written, particularly if there is another preprocessor involved. To avoid needless proliferation of tags, and still permit unambiguous execution of complex TAL, a precedence order was chosen according to the following rationale. The reasoning behind this ordering goes like this: You often want to set up variables for use in other statements, so ``define`` comes first. Then any switch statement. The very next thing to do is decide whether this element will be included at all, so ``condition`` is next; since the condition may depend on variables you just set, it comes after ``define``. It is valuable be able to replace various parts of an element with different values on each iteration of a repeat, so ``repeat`` is next, followed by ``case``. It makes no sense to replace attributes and then throw them away, so ``attributes`` is last. The remaining statements clash, because they each replace or edit the statement element. attributes: Replace element attributes ====================================== Syntax ++++++ tal:attributes syntax:: argument ::= attribute_statement [';' attribute_statement]* attribute_statement ::= attribute_name expression attribute_name ::= [namespace-prefix ':'] Name namespace-prefix ::= Name *Note: If you want to include a semi-colon (;) in an `expression`, it must be escaped by doubling it (;;).* Description +++++++++++ The ``tal:attributes`` statement replaces the value of an attribute (or creates an attribute) with a dynamic value. You can qualify an attribute name with a namespace prefix, for example:: html:table if you are generating an XML document with multiple namespaces. The value of each expression is converted to a string, if necessary. If the expression associated with an attribute assignment evaluates to *nothing*, then that attribute is deleted from the statement element. If the expression evaluates to *default*, then that attribute is left unchanged. Each attribute assignment is independent, so attributes may be assigned in the same statement in which some attributes are deleted and others are left alone. If you use ``tal:attributes`` on an element with an active ``tal:replace`` command, the ``tal:attributes`` statement is ignored. If you use ``tal:attributes`` on an element with a ``tal:repeat`` statement, the replacement is made on each repetition of the element, and the replacement expression is evaluated fresh for each repetition. Examples ++++++++ Replacing a link:: Replacing two attributes::