Syntax
PathExpression ::= Expression [ '|' Expression ]* PathSegmentExpression ::= FirstPathToken [ '/' NextPathToken ]* FirstPathToken ::= StringLiteral | NumericLiteral | BooleanLiteral | ListExpression | FunctionExpression | VariableExpression | ArrayExpression StringLiteral ::= '/'' StringLiteralChar* '/'' StringLiteralChar ::= any character except ''' NumericLiteral ::= Numeric+ BooleanLiteral ::= true | false ListExpression ::= '[' Expression ']' RangeExpression ::= Numeric* ':' Numeric+ [ ':' Numeric+ ] FunctionExpression ::= Name '(' [ ArgumentList ] ')' VariableExpression ::= Name ArrayExpression ::= Expression ArrayAccessor ArrayAccessor ::= '[' Expression+ ']' NextPathToken ::= IndirectionExpression | MethodExpression | PropertyExpression | ArrayAccessor IndirectionExpression ::= '?' Name MethodExpression ::= Name '(' [ ArgumentList ] ')' PropertyExpression ::= Name ArgumentList ::= Expression [ ',' Expression ]*
Description
A path expression consists of a path optionally followed by a vertical bar (|) and alternate expression. A path consists of one or more non-empty strings separated by slashes.
The first string must be one of these:
- a string literal,
- a numeric literal,
- a boolean literal,
- a list expression,
- a function expression,
- an array expression,
- or a variable name (a built-in variable or a user defined variable).
The remaining strings, the path segments, may be:
- an indirection,
- a method name,
- an array accessor,
- or a property name.
When a path expression is evaluated, ZPT-JS attempts to traverse the path, from left to right, until it succeeds or runs out of paths segments. To traverse a path, it first fetches the object stored in the variable. For each path segment, it traverses from the current object to the sub-object named by the path segment.
Once a path has been successfully traversed, the resulting object is the value of the expression. If it is a callable object, such as a method or function, it is called.
If a traversal step fails, and no alternate expression has been specified, an error results. Otherwise, the alternate expression is evaluated.
The alternate expression can be any TALES expression. For example:
user/name | 'Anonymous Coward'
is a valid path expression. This is useful chiefly for providing default values, such as strings and numbers, which are not expressible as path expressions. Since the alternate expression can be a path expression, it is possible to chain path expressions, as in:
first | second | third | nothing
If no path is given the result is nothing
.
Note: some parts extracted from Zope Page Templates Reference.
Differences with ZPT
- ZPT-JS includes more types of path expressions, such as method, array, list or range expressions.
- ZPT uses python expressions for a lot of tasks, but these are not supported in ZPT-JS.
Examples
The neccesary javascript code:
"use strict"; var zpt = require( 'zpt' ); var dictionary = { number100: 100, aString: "string", function3: function( ){ return 3; }, add: function( a, b ){ return a + b; }, user: { name: "Bob", age: function(){ return 25; }, birth: function(){ return { day: 3, month: 3, year: 1977, aFunction: function(){ return { another: 'yes!' }; } }; }, addMethod: function( a, b ){ return a + b; } }, items: [ 'first', 'second', 'third' ], from1To3: [ 1, 2, 3 ], property: "name" }; // Parse template zpt.run({ root: document.body, dictionary: dictionary });
Literals
Literals are constant values. They can be number, string or boolean values:
<span data-content="'this is a string literal'">a string</span> <span data-content="123">an integer</span> <span data-content="123.45">a float</span> <span data-content="true">not false</span> <span data-content="false">not true</span>
Functions
Invoking functions:
<span data-content="function3()">must be 3</span> <span data-content="add( 1, 2 )">must be 1 + 2 = 3</span> <span data-content="add( 1, number100 )">must be 1 + number100 = 101</span> <span data-content="add( 1, (*: 2 2 ) )">must be 1 + 2 * 2 = 5</span>
Variables
Using simple variables:
<span data-content="number100">must be 100</span> <span data-content="aString">must be string</span>
Properties
Using properties of objects:
<span data-content="user/name">must be Bob</span>
Methods
Using methods of objects:
<span data-content="user/age()">must be 25</span> <span data-content="user/addMethod( 1, 2 )">must be 1 + 2 = 3</span>
Arrays
Arrays are supported too:
<span data-content="items[2]">must be third</span> <span data-content="items">must be first, second, third</span> <span data-content="+: from1To3 4">must be 1 + 2 + 3 + 4 = 10</span>
Maps
Maps support makes it easy to access defined in variables properties:
<span data-content="user['name']">must be Bob</span> <span data-define="property 'name'" data-content="user[ property ]">must be Bob again</span>
Lists
Lists are very versatile:
<span data-content="[1 20 3 number100]">must be 1,20,3,100</span> <span data-content="+: [1 20 3 number100]">must be 1 + 20 + 3 + 100 = 124</span> <ol> <li data-repeat="c [1 20 3 number100]"> Iterating element <span data-content="c">1/20/3/100</span> </li> </ol> <ol> <li data-repeat="c [1 'a string' number100]"> Iterating element <span data-content="c">1/a string/100</span> </li> </ol>
Ranges
Ranges makes it easy buildin numeric lists:
<ol> <li data-repeat="c [1:5]"> Iterating element <span data-content="c">1/2/3/4/5</span> </li> </ol> <ol> <li data-repeat="c [1:7:2]"> Iterating element <span data-content="c">1/3/5/7</span> </li> </ol> <ol> <li data-repeat="c [:5]"> Iterating element <span data-content="c">0/1/2/3/4/5</span> </li> </ol>
Indirections
<span data-content="user/?property">must be Bob if property is name</span>