ZPT reference
The ZPT syntax/language is organised into three logical parts. Each primary mention of an attribute below is a link to its reference page.
METAL is for reusing markup
When processing a ZPT source document, the first attributes processed (through the entire document) are METAL attributes. Only once all METAL attributes are processed does ZptSharp process TAL attributes.
The concept at the heart of METAL is macros. A macro is a reusable subtree of an HTML or XML document. In other words, it is an element and all of that element's descendents & content. Macros are created using the metal:define-macro
attribute and reused within a document with the metal:use-macro
attribute.
METAL macros may also contain zero or more slots. Slots are also single elements which may be replaced ('filled') at the point where the macro is used. Slots are created with the metal:define-slot
attribute and are used/filled using the metal:fill-slot
attribute.
An advanced usage of METAL is macro extension. This is somewhat similar in concept to creating a 'subclass' of a macro. The metal:extend-macro
attribute is how this is performed.
TAL binds data to the template
TAL attributes are parsed and resolved after METAL attributes. The purpose of TAL is to bind/write your model and supporting data to the template.
The table below shows and links to the various TAL attributes. It also shows the order in which they are processed (if, for example, multiple attributes appear on the same element).
Order | Attribute | Summary |
---|---|---|
1st | tal:define |
Creates variables which are usable by subsequent directives. |
2nd | tal:condition |
Removes the element if the associated expression is not "truthy" |
3rd | tal:repeat |
Repeats the element (and contents) for each item in an IEnumerable |
4th* | tal:content |
Replaces the element's contents with a value from an expression |
4th* | tal:replace |
Replaces the whole element with a value from an expression |
5th | tal:attributes |
Sets attributes upon the element using expression values |
6th | tal:omit-tag |
Removes the start & end tags of an element, whilst preserving its content/children |
N/A** | tal:on-error |
Handles processing errors on the current element and children (similar to a C# catch ) |
Notes for the above table
- * TAL content and replace attributes are mutually exclusive. It is invalid for the same element to have both.
- ** The on-error attribute does not fit into the usual order of processing. It is only processed if/when an error occurs.
TALES is how expressions are written
Both METAL and TAL attributes make use of expressions to locate the desired macros, content or logic. TALES is an extensible syntax and so plugins may add further expression types. These are the expression types which are officially supported by ZptSharp.
In the examples below all expressions are shown using their fully qualified/prefixed names. Every rendering operation has a default expression type which does not require a prefix. If not specified otherwise using the configuration, this default type will be path expressions.
Name | Summary |
---|---|
path |
Provide access to objects using a syntax which looks a lot like the path portion of a URL. For example path:here/Customers/3/Name |
string |
Create interpolated strings including content from other expressions. For example string:Hello ${path:name}, how are you? |
not |
Coerce another expression result to boolean, then negate it. For example not:path:loan/IsOverdue |
pipe |
Use a delegate to transform a value. For example pipe:name path:pipes/ToLowercase |
csharp |
Evaluate arbitrary C# expressions (but please read about the limitations). For example csharp:name.ToLowerInvariant() |
python |
Evaluate arbitrary expressions written in the Python 2 language. For example python:2 + 2 |
structure |
Indicates that an 'inner' expression should be interpreted as structure/markup when rendered. For example structure:path:here/SomeMarkup |
In XML documents, namespaces matter
The metal
and tal
attribute prefixes used throughout ZPT are defined with the following XML namespaces:
Prefix | Namespace |
---|---|
metal |
http://xml.zope.org/namespaces/metal |
tal |
http://xml.zope.org/namespaces/tal |
When working with XML document templates, these two namespaces must be declared (typically at the root of the document) via xmlns
attributes.
Strictly-speaking, for an XML document the namespaces are all that matters, you could conveivably use aliases which are not tal
or metal
, although for readability's sake this is not advised.
When using HTML documents the namespaces need not be declared; the metal
and tal
prefixes are recognised by their prefix names alone.
XML namespaces example
<root xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:tal="http://xml.zope.org/namespaces/tal">
<child tal:content="string:Some content">This content attribute will work OK.</child>
</root>
Elements in the TAL or METAL namespace
A feature of the ZPT syntax is elements which use the tal
or metal
prefix (or, for XML documents, elements in the namespaces listed in the previous section).
Elements which are prefixed with either tal
or metal
may be 'invented' by the designer, the element name after the prefix is irrelevant.
Such elements are detected by ZptSharp during rendering and their start/end tags are always omitted from the rendered output as if they had a tal:omit-tag=""
attribute present.
What's more, all attributes upon a TAL or METAL element are automatically assumed to be TAL or METAL attributes (accordingly).
This means that within such an element, the tal:
or metal:
prefixes are not required for attributes.
The use-case for TAL & METAL elements is to allow use of TAL & METAL attributes in positions where no other markup element would semantically make sense. This scenario does not occur very often and so it is not expected that this technique will be frequently used.
TAL element example
Here is a somewhat contrived example.
For the purpose of this example, presume that we cannot alter the <ul>
element and add attributes to it.
Perhaps the <ul>
element is part of a macro which we do not wish to alter.
<ul>
<tal:defs define="items here/Items | here/OtherItems | here/EmptyArray">
<li tal:repeat="item items" tal:content="item/Name">Item name</li>
</tal:defs>
</ul>
In a real application, we could more likely add the complex tal:define
attribute onto the <li>
element.
Because define attributes are processed before content attributes we would get the same result without needing a TAL element.