ZPT-JS reference - Path expressions

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:

The remaining strings, the path segments, may be:

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

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>