*Title: Improved template syntax *Incentive: To make template syntax clearer and more similar to syntax of widespread procedural programming languages. *Documentation: 1 Variables =========== 1.1 Dollar sign ----------- We will use dollar sign ($) everywhere a variable is used, including assignments. Example: {set $i=10} i: {$i} Old-style assignments without "$" shall work. 1.2 New functions to create/destroy variables ----------------------------------------- We should avoid usage of {let}...{/let} block since it makes harder to read tpl file and move code within it. Instead, two new functions proposed: {def} and {undef}: - def creates a new variable in the current namespace and assigns a value to it. - undef destroys given variable, in a manner like the corresponding PHP operator does. Syntax: {def $var1= [$var2= ...]} {undef [$var1 [$var2] ...]} Example: {def $i=10 $j=20} {def $s1='hello' $s2='world'} ... {set $i=$i+1} ... {undef $i} {undef $s1 $s2} {undef} If the variable being created already exists, {def} shows a warning message and doesn't do anything except of assigning new value to the variable. {undef} destroys all variables when called without arguments. 1.3 Variables scope --------------- Variables created with {def} exist till the end of file, unless destroyed with {undef}. A template file opens (and closes) a new scope. 2 New control structures ====================== A few new control structures are proposed. They are meant to be much simplier to understand and use by developers than the allmighty {section} function. 2.1 IF statement ------------ Syntax: {if } [{elseif }] [{else}] {/if} Example: {if eq( $var, true() )} Hello world {else} No world here, move along. {/if} 2.2 WHILE statement --------------- Syntax: {while [sequence as $seqVar] } [{delimiter}...{/delimiter}] [{break}] [{continue}] [{skip}] {/while} Example: {while ne( $var, false() ) } I like big trucks {/while} 2.3 DO..WHILE statement ------------------- Syntax: {do} [{delimiter}...{/delimiter}] [{break}] [{continue}] [{skip}] {/do while [sequence as $seqVar]} Example: {do} One more beer, please. {/do while eq( $drunk, false() )} 2.4 FOR statement ------------- Syntax: {for to as $itemVar [sequence as $seqVar]} [{delimiter}...{/delimiter}] [{break}] [{continue}] [{skip}] {/for} Examples: {for 1 to 5 as $i} i: {$i} {/for} {for 5 to 1 as $i} i: {$i} {/for} $itemVar is destroyed after the loop ends. 2.5 FOREACH statement ----------------- Syntax: {foreach as [$keyVar =>] $itemVar [sequence as $sequenceVar] [offset ] [max ] [reverse]} [{delimiter}...{/delimiter}] [{break}] [{continue}] [{skip}] {/foreach} Examlple: {foreach $objects as $object} {foreach $object.nodes as $node sequence array(dark,light) as $class} {$node.name|wash} {/foreach} {/foreach} Variables $keyVar, $itemVar and $sequenceVar are destroyed after the loop ends. {foreach} does not support iterating through strings like {section loop=...} does. So, {foreach $string as $character} will not work. {foreach} also does not support iterating within a numeric range, like {section loop=NUMBER} did. You should use {for} instead. Also, {foreach} does not use the proxy iterator as {section loop=...} does. ie you cannot do: {$node.key}, {$node.index}. Prameters 'offset', 'max' and 'reverse' have the same meaning as in {section}. 2.6 Notes on the loop functions --------------------------- All the new loop functions support the following features: - 'sequence' optional parameter: array to cycle through continuously. - {delimiter} function: piece of code/text executed/shown after each iteration, except of the last one. - {break} function: immediately terminate the loop. - {continue} function: go to the next loop iteration, executing {delimiter} if specified. - {skip} function: go to the next loop iteration, without executing {delimiter}. The {delimeter} construct must be placed as a direct child of the loop construct. e.g. this should not be possible: {foreach ...} {if eq( $item, 5 )} {delimiter}----{/delimiter} {else} {delimiter}===={/delimiter} {/if} {/foreach} Instead it must be written as: {foreach ...} {delimiter} {if eq( $item, 5 )} ---- {else} ==== {/if} {/delimiter} {/foreach} The {skip}, {continue} and {break} functions can be used as a child no matter how deep. In other words they will react to the last looping construct that was in effect. *Note* that if you have a code similar to "{section var=start loop=array( 1, 2 )}..." you cannot use $start as parameter of the new loop functions directly, instead you should use $start.item. That is, section loop proxy iterators must be previously dereferenced. Online version of this article can be found here: http://ez.no/community/developer/specs/improved_template_syntax