EBNF ==== Program ------- The template language starts with the non-terminal token: "Program". :: Program ::= Version NewLine Code EOF Version ::= '{?' 'ezt' 'version' '=' '"' FloatLiteral '"' '}' Code ::= ( Text | Block )* Text ::= TextBlock | LiteralBlock | DelimiterBlock Block ::= CommentBlock | DeclarationBlock | ModifyingBlock | OutputBlock | LiteralBlock | CycleBlock | LoopBlock | CodeFlowBlock | CustomBlock Text blocks ----------- :: TextBlock ::= ( ~'{' | '\'! '{' )* LiteralBlock ::= '{' 'literal' '}' Graphic* '{' '/literal' '}' DelimiterBlock :== '{ldelim}' | '{rdelim}' Blocks ------ :: CommentBlock ::= '{*' Graphic* '*}' DeclarationBlock ::= '{' 'var' SubDefineBlock '}' | '{' 'cycle' SubDefineBlock '}' | '{' 'use' SubDefineBlock '}' SubDefineBlock ::= PrimaryVariable ( '=' Expression )? ( ',' SubDefineBlock )? ModifyingBlock ::= '{' SubAssignBlock (',' SubAssignBlock)* '}' SubAssignBlock ::= AssignmentExpr | IncrementExpr | DecrementExpr AssignmentExpr ::= PrimaryVariable ( '=' | CombinedAssignment) Expression IncrementExpr ::= ( ( '++' PrimaryVariable ) | ( PrimaryVariable '++' ) ) DecrementExpr ::= ( ( '--' PrimaryVariable ) | ( PrimaryVariable '--' ) ) OutputBlock ::= '{' Expression '}' CycleBlock ::= '{' 'increment' PrimaryVariable ( ',' PrimaryVariable )* '}' | '{' 'decrement' PrimaryVariable ( ',' PrimaryVariable )* '}' | '{' 'reset' PrimaryVariable ( ',' PrimaryVariable )* '}' Loop control ------------ :: LoopBlock ::= ForeachStatement | WhileStatement ForeachStatement ::= '{' 'foreach' Expression 'as' PrimaryVariable ('=>' PrimaryVariable)? (Cycle)* (OffsetAndLimit)? '}' Code '{' '/foreach' '}' WhileStatement ::= '{' 'while' Expression '}' Code '{' '/while' '}' Cycle ::= ('increment' | 'decrement') PrimaryVariable (',' PrimaryVariable)* OffsetAndLimit ::= ('offset' Expression)? ('limit' Expression)? Code flow control ----------------- :: CodeFlowBlock ::= IfStatement | SwitchStatement | IncludeStatement | DelimiterStatement | '{break}' | '{skip}' | '{continue}' | ReturnStatement IfStatement ::= '{' 'if' Expression '}' Code (ElseIf)* (Else)? '{' '/if' '}' ElseIf ::= '{' 'elseif' Expression '}' Code Else ::= '{' 'else' '}' Code SwitchStatement ::= '{' 'switch' Expression '}' (Case)* (DefaultCase)? '{' '/switch' '}' Case ::= '{' 'case' Literal ( ',' Literal)* '}' Code '{' '/case' '}' DefaultCase ::= '{' 'default' '}' Code '{' '/default' '}' IncludeStatement ::= '{' 'include' Expression ('send' ExprAsPrimVarList)? ('receive' PrimVarAsPrimVarList)? '}' DelimiterStatement ::= '{' 'delimiter' (modulo Expression ('is' Expression)? )? '}' Code '{' '/delimiter' '}' ReturnStatement ::= '{' 'return' ExprAsPrimVarList '}' ExprAsPrimVarList ::= ( Expression 'as' PrimaryVariable | PrimaryVariable ) (',' ExprAsPrimVarList)? PrimVarAsPrimVarList::= PrimaryVariable ('as' PrimaryVariable)? (',' PrimVarAsPrimVarList)? Custom block ------------ :: CustomBlock ::= '{' Identifier ( Expression )? ( CustomArgument )* '}' (Code '{' '/'Identifier '}')? CustomArgument ::= Identifier ( ('=')? Expression)? Expression ---------- :: Expression ::= PreUnaryExpression (BinaryOperator Expression)? PreUnaryExpression ::= '++' PrimaryVariable | '--' PrimaryVariable | UnaryExpression | Expression 'instanceof' Identifier | ArrayDeclaration ArrayDeclaration ::= 'array' '(' ( (Expression '=>')? Expression ( ',' Expression )* (',')? )? ')' | Expression '..' Expression UnaryExpression ::= ( UnaryOperator )* PostFixExpression PostFixExpression ::= PrimaryVariable ( '++' | '--' )? | Literal | FunctionCall | '(' Expression ')' PrimaryVariable ::= '$' Identifier ( '[' Expression ']' | '->' Expression )* FunctionCall ::= Identifier '(' (ParameterList)? ')' ParameterList ::= Expression ( ',' Expression )* Identifier ::= Letter ( Letter | Digit | '_' )* Basic literals -------------- :: Literal ::= NumeralLiteral | StringLiteral | BooleanLiteral | NullLiteral NumeralLiteral ::= HexLiteral | OctLiteral | FloatLiteral HexLiteral ::= '0x' HexDigit+ OctLiteral ::= '0' OctDigit+ FloatLiteral ::= NonZeroDigit Digit* ( '.' Digit+ )? (('e'|'E') ('+'|'-')? Digit+)? StringLiteral ::= '"' Graphic* '"' | "'" Graphic* "'" BooleanLiteral ::= 'true' | 'false' NullLiteral ::= 'null' Lexicon ------- :: Comment ::= '//' Graphic* ( EOL | '}' ) | '/*' Graphic* '*/' Graphic ::= Digit | Letter | Blank | Operators | Assignment | CombinedAssignment | RemainingCharSet EOL ::= end-of-line EOF ::= end-of-file Blank ::= Tab | Space NewLine ::= '\n' Space ::= ' ' Tab ::= '\t' Letter ::= 'a' ... 'z' | 'A' ... 'Z' Hexdigit ::= '0' .. '9' | 'A' .. 'F' Octdigit ::= '0' .. '8' NonZeroDigit ::= '1' .. '9' Digit ::= '0' | NonZeroDigit Assignment ::= '=' CombinedAssignment ::= '+=' | '-=' | '*=' | '/=' | '%=' | '.=' Operators ::= BinaryOperator | UnaryOperator | '++' | '--' BinaryOperator ::= ArithmeticOperator | ComparisonOperator | BooleanOperator | StringOperator ArithmeticOperator ::= '+' | '-' | '*' | '/' | '%' ComparisonOperator ::= '==' | '===' | '!=' | '!==' | '<' | '<=' | '>' | '>=' BooleanOperator ::= '&&' | '||' StringOperator ::= '.' | '.=' UnaryOperator ::= '+' | '-' | '!' RemainingCharSet ::= '.' | ':' | ';' | ',' | '~' | '(' | ')' | '[' | ']' | '{' | '}' | '_' | '|' | "'" | '"' | '`' | '#' | '$' | '@' Examples ======== Text ---- Normal text output ^^^^^^^^^^^^^^^^^^ The next example writes "hello world":: {?ezt version="1.0" } Hello world Using ldelim and rdelim ^^^^^^^^^^^^^^^^^^^^^^^ Template:: {?ezt version="1.0" } {ldelim}?ezt version="1.0"{rdelim} writes {?ezt version="1.0"} to the output. Comments -------- Block comments ^^^^^^^^^^^^^^ The following template:: {?ezt version="1.0"} {* Hello *} world will only output "world". Inline comments ^^^^^^^^^^^^^^^ :: { // Hello } world { // Hello } earth outputs:: world earth c-comment ^^^^^^^^^ :: { /* Hello */ "world" } outputs:: world Foreach ------- Foreach-ing over an array ^^^^^^^^^^^^^^^^^^^^^^^^^ :: {var $colors = array( "red" => "#FF0000", "green" => "#00FF00" )} {foreach $colors as $name => $value} $name {/foreach} Counting from 1 to 10 ^^^^^^^^^^^^^^^^^^^^^ Using a function:: {foreach array_range(1, 10) as $value} Iteration number: {$value} {/foreach} Or the short notation:: {foreach 1..10 as $value} Iteration number: {$value} {/foreach} Using the cycle ^^^^^^^^^^^^^^^ :: {* Declaring the $blackAndWhite cycle *} {cycle $blackAndWhite = array( '#00000', '#FFFFFF' )} {foreach 1..10 as $value increment $blackAndWhite} Numbers: {$value} {/foreach} Using offset and limit ^^^^^^^^^^^^^^^^^^^^^^ :: {var $hugeArray = 1..1000 {*show number 50 to 100 *} {foreach $hugeArray as $value offset 50 limit 50} My favourite numbers are: {$value} {/foreach} While ----- Counting from 1 to 10 ^^^^^^^^^^^^^^^^^^^^^ :: {var $i = 0} {while $i <= 10} Number: {$i} {$i++} {/while} Using the cycle ^^^^^^^^^^^^^^^ For the while loop, you have to do the cycling yourself. Note that the while loop is used rarely. :: {var $i = 0} {cycle $oddOrEven = array("odd", "even")} {while $i <= 10} Number {$i} is {$oddOrEven} {increment $oddOrEven} {$i++} {/while} If -- :: {var $i = 10} {if $i % 2 == 0} The number is even. {elseif $i % 2 == 1} The number is odd. {else} The number is neither odd nor even. Which is a tiny bit strange. {/if} Switch ------ :: {var $number = 4} {switch $number} {case 1} One {/case} {case 2} Two {/case} {case 3,4,5} Three, Four, or Five {/case} {default} Any number except 1 to 5. {/default} {/switch} Properties ---------- Use ^^^ The nodes: $node and $optionalNode come from the application, and need therefore be known in the template code. If the $optionalNode is not set, it will get the default value "false":: {use $node, $optionalNode = false} Accessing a property ^^^^^^^^^^^^^^^^^^^^ :: {use $node, $optionalNode = false} Impressive title: {$node->impressiveTitle} Norwegian title: {$node->titles["norwegian"]} {if $optionalNode != false} Extra title: {$optionalNode->titles["norwegian"]} {/if} Dynamic names ^^^^^^^^^^^^^ :: {use $node} {$property = "impressive" . "Title"} Impressive title: {$node->$property} Delimiter --------- :: {var $columns = 4}
{$nr} | {delimiter modulo $columns /* is 0 */ }