| |
| 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} |
| <font color="{$value}">$name</font> |
| {/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} |
| <font color="{$blackAndWhite}">Numbers: {$value}</font> |
| {/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} |
| <table> |
| <tr> |
| {foreach 1..12 as $nr} |
| <td>{$nr}</td> |
| |
| {delimiter modulo $columns /* is 0 */ } |
| </tr><tr> |
| {/delimiter} |
| |
| {/foreach} |
| </tr> |
| |
| |
| Including templates |
| ------------------- |
| :: |
| |
| {use $currentNode} |
| |
| {* Call the template with the variable $node that contains the value $currentNode *} |
| {include 'showAndAlterNode.tpl' |
| send $currentNode as $node |
| receive $node as $alteredNode} |
| {* The template returns a $node, but we rename it to $alteredNode *} |
| |
| |
| {* Rename the $alteredNode to $currentNode *} |
| {return $alteredNode as $currentNode} |
| |
| |
| .. |
| Local Variables: |
| mode: rst |
| fill-column: 79 |
| End: |
| vim: et syn=rst tw=79 |