| eZ publish Enterprise Component: Component, Design |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| :Author: Jan Borsodi |
| :Revision: $Revision$ |
| :Date: $Date$ |
| |
| Design description |
| ================== |
| |
| Elements |
| -------- |
| |
| Elements are the internal types used by the engine to represent the syntax of a |
| template file. Elements are dividied into several groups and each is explained |
| in detail. |
| |
| .. figure:: template_elements.png |
| |
| All template elements. |
| |
| Comments |
| ^^^^^^^^ |
| |
| Comments are text blocks which will be stripped away from the output when the |
| template is executed. Comments can be standalone spanning an entire tag or |
| placed inline in template code. |
| Comments can be used for explaining what or why something is done or to comment |
| out code which is no longer to be used. |
| |
| Code comments |
| ````````````` |
| |
| Code comments are created by starting and ending the tag with an asterix |
| (\*). Whatever is inside is considered comments for the template code:: |
| |
| {* Comment text *} |
| {* Comments can |
| also span |
| multiple lines *} |
| |
| The comment will be read as it is with newlines. |
| |
| Inline comments |
| ``````````````` |
| |
| Inline comments are created using \/\* and \*\/ or with \/\/. Use the \/\* to |
| span multiple lines \/\* or the \/\/ to start a comment which continues to the |
| end of the line:: |
| |
| {def $a = 1 /*, $b = 2, */, $c = 3 } |
| {def $a = 1 //, $b = 2 |
| , $c = 3} |
| |
| These comments are usually something you use while developing but isn't left in |
| after a release is made. If the result after removing the inline comments is an |
| empty tag the tag itself will be ignored:: |
| |
| { /* def $a = 1 */ } |
| |
| Expressions |
| ^^^^^^^^^^^ |
| |
| Expressions are not a real element but rather a way of thinking a combination |
| of elements. For instance each operator of an operator can be any kind of |
| element (including new operators) which in the end forms a composition tree. |
| |
| .. figure:: template_element_composition.png |
| |
| Example composition structure. |
| |
| Builtins |
| ^^^^^^^^ |
| |
| The language comes with several builtin expression for types and structures to |
| make it easier to use. |
| |
| Booleans are created with the *true* or *false* names, for instance:: |
| |
| true |
| false |
| $a = true |
| |
| Integers and floats are written as in PHP using:: |
| |
| 1 |
| 1.0 |
| |
| Creating strings is done using single or double quotes, single quotes takes the |
| characters literally and doesn't allow escaping while the double quotes allows |
| escaping:: |
| |
| "a simple string" |
| 'another simple string' |
| "with the escaped characters \"\n\r\t\\" |
| 'no escaping in here \"\n\r\t\\' |
| |
| Create arrays and hashes with the syntax:: |
| |
| array( $v1 [, $v2 ...] ) |
| array( $k1 => $v1 [, $k2 => $v2 ...] ) |
| |
| Functions |
| ^^^^^^^^^ |
| |
| .. Todo: Update this text. |
| |
| A function is a piece of reusable code which can be called with parameters. |
| The function will perform some PHP code and return a value based on the |
| parameters. Parameterless functions are also possible. |
| |
| Functions can either be programmed by implementing the ezcTemplateFunction |
| interface or mapping them to PHP functions or expressions. |
| |
| The template language must supply the required functions for the most common |
| operations. The names should not follow the confusing and inconsistent naming |
| of PHP functions but provide a clean and easy to understand set (As reference |
| some of the names in the Qt library have been used, e.g. methods in QString) |
| |
| See design_functions.txt for a list of functions which will be part of the |
| template language as a standard. |
| |
| Operators |
| ^^^^^^^^^ |
| |
| Operators are part of an expression and can modify the value or transform it |
| into another value. Examples of operators are adding two numbers together (+) |
| or checking for equality (==). Operators takes one, two or three operands |
| (called unary, binary and terniary operators). |
| |
| The operator precedence is as follows (some are missing): |
| |
| =============== ==================== |
| Associativity Operators |
| =============== ==================== |
| right [ ->(left) |
| non-associative ++ -- |
| non-associative ! - instanceof |
| left \* / % |
| left \+ \- . |
| non-associative < <= > >= |
| non-associative == != === !== |
| left && |
| left || |
| left ? : |
| right = += -= \*= /= .= %= |
| =============== ==================== |
| |
| .. figure:: template_operators.png |
| |
| Some of the operator classes. |
| |
| Arithmetic operators |
| ```````````````````` |
| |
| The arithmetic operators can be used on all expression which returns a |
| numerical value (integer or float). |
| |
| ============== =========== |
| Negation -$o |
| Addition $ol + $or |
| Subtraction $ol - $or |
| Multiplication $ol * $or |
| Division $ol / $or |
| Modulus $ol % $or |
| ============== =========== |
| |
| |
| Assignment operator |
| ``````````````````` |
| |
| The assignment operator can be used to assign the value of an expression to a |
| variable or an entry in an array. |
| |
| ========== ========= |
| Assignment $ol = $or |
| ========== ========= |
| |
| Note: Assignment is only allowed with some functions and blocks |
| |
| See also `Combined operators`_ |
| |
| Combined operators |
| `````````````````` |
| |
| ============== ============ |
| Addition $ol += $or |
| Subtraction $ol \-= $or |
| Multiplication $ol \*= $or |
| Division $ol /= $or |
| Modulus $ol %= $or |
| Concat $ol .= $or |
| ============== ============ |
| |
| Comparison operators |
| ```````````````````` |
| |
| ===================== ============ |
| Equal $ol == $or |
| Identical $ol === $or |
| Not equal $ol != $or |
| Not identical $ol !== $or |
| Less than $ol < $or |
| Greater than $ol > $or |
| Less than or equal $ol <= $or |
| Greater than or equal $ol >= $or |
| ===================== ============ |
| |
| Increment/decrement operators |
| ````````````````````````````` |
| |
| ============== ==== |
| Pre increment ++$o |
| Pre decrement --$o |
| Post increment $o++ |
| Post decrement $o-- |
| ============== ==== |
| |
| Logical operators |
| ````````````````` |
| |
| === ========== |
| Not ! $o |
| And $ol && $or |
| Or $ol || $or |
| === ========== |
| |
| Flow operator |
| ````````````` |
| ============ =================== |
| If/then/else $if ? $then : $else |
| ============ =================== |
| |
| String operators |
| ```````````````` |
| |
| ============= ========= |
| Concatenation $ol . $or |
| Substring $ol[$or] |
| ============= ========= |
| |
| See also `Combined operators`_ |
| |
| |
| Array operators |
| ``````````````` |
| |
| ===================== ============ |
| Equal $ol == $or |
| Identical $ol === $or |
| Not equal $ol != $or |
| Not identical $ol !== $or |
| Union $ol + $or |
| Key value $ol[$or] |
| Append $ol[] = $or |
| ===================== ============ |
| |
| See also `Combined operators`_ |
| |
| Object operators |
| ```````````````` |
| |
| ===================== =========== |
| Equal $ol == $or |
| Identical $ol === $or |
| Not equal $ol != $or |
| Not identical $ol !== $or |
| Property lookup $ol->or |
| ===================== =========== |
| |
| Modifiers |
| ^^^^^^^^^ |
| |
| Note: This is probably skipped, conflicts with the rest of the syntax |
| |
| Blocks |
| ^^^^^^ |
| |
| Blocks are nested structure which performs a given operation on their children. |
| For instance it can execute the children and then transform the text result |
| into something else. |
| |
| .. figure:: template_blocks.png |
| |
| Some of the block classes. |
| |
| Curly braces |
| ```````````` |
| |
| Since the curly braces are used for the invocation of the template syntax they |
| cannot be used directly in plain text anymore. To get around this you can |
| escape the brace with a backslash (\):: |
| |
| function code() |
| \{ |
| \} |
| |
| It is also possible to use the specialized ldelim and rdelim blocks to output |
| them:: |
| |
| function code() |
| {ldelim} |
| {rdelim} |
| |
| Lastly it can also be placed inside a text string:: |
| |
| function code() |
| {"{"} |
| {"}"} |
| |
| Literal text |
| ```````````` |
| |
| If you want to enter lots of code or text which should not be processed by the |
| template language you can place the code inside *literal* blocks. Any text |
| within this block is read as it is (even back slashes) until a {/literal} is |
| reached:: |
| |
| {literal} |
| function code() |
| { |
| } |
| {/literal} |
| |
| Text manipulation |
| ````````````````` |
| .. Note: These entries are only a suggestion. |
| |
| - block start/block end |
| |
| Captures the output of the child elements and performs wrapping, indentation |
| and end-of-line style on the result. This can be used to generate lots of |
| text with template code and then wrap it into a readable text format:: |
| |
| {block [wrap column] [indent prefix] [eol suffix]} |
| {/block} |
| |
| Parameters: |
| |
| - wrap - Which column to wrap at, if not supplied the current context wrap is |
| used. |
| - indent - A text piece to indent each line with (after wrap), this will be |
| appended to any existing indent text. |
| - eol - A text piece to replace the newline character for each line (after |
| wrap). |
| |
| Example #1, generating mail reply:: |
| |
| {block wrap 79 indent "> "} |
| ... render mail reply here: |
| {/block} |
| |
| Example #2, wrapping with html hard breaks:: |
| |
| {block wrap 70 eol "<br/>"} |
| {/block} |
| |
| - table/tr/th/td |
| |
| A set of blocks to easy the generation of plain text tables:: |
| |
| {table} |
| {tr} |
| {th}Header1{/th} |
| {th}Header2{/th} |
| {/tr} |
| {tr} |
| {td}Element1{/td} |
| {td}Element2{/td} |
| {/tr} |
| {tr} |
| {td}Element3{/td} |
| {td}Element4{/td} |
| {/tr} |
| {/table} |
| |
| - matrix/md/mh |
| |
| Easy generation of plain text matrices:: |
| |
| {matrix 3 by 3} |
| {mh}X{/mh} |
| {mh}Y{/mh} |
| {mh}Z{/mh} |
| {md}1{/md} |
| {md}2{/md} |
| {md}3{/md} |
| {md}4{/md} |
| {md}5{/md} |
| {md}6{/md} |
| {md}7{/md} |
| {md}8{/md} |
| {md}9{/md} |
| {/matrix} |
| |
| - cleanup (XML/XHTML only) |
| |
| Renders the child blocks and cleans up excess whitespace from the output to |
| reduce whitespace which is only present for being human readable. This is |
| something that is done once a project is finished to reduce bandwidth. |
| |
| Cleanup blocks can be turned on or off globally to aid in development of |
| templates:: |
| |
| {cleanup} |
| <p> |
| |
| This contains quite |
| a lot of |
| |
| unneccesary whitespace. |
| </p> |
| {/cleanup} |
| |
| - tidy (XML/XHTML only) |
| |
| Renders the child blocks and then tries to rearrange the XML/XHTML structure |
| to be more readable. This can be used while developing to make it clearer |
| where errors occur in XML/XHTML output:: |
| |
| {tidy} |
| .... |
| {/tidy} |
| |
| Control structures |
| ^^^^^^^^^^^^^^^^^^ |
| |
| Control structures are elements which help you control the flow of the code, |
| either by doing conditional statements or by repeating certain actions. |
| Control structures can exist both as Blocks and inline code. |
| |
| .. figure:: template_control_structures.png |
| |
| Some of the control structure classes. |
| |
| Control structures for looping are: |
| |
| - foreach |
| |
| - for |
| |
| - while |
| |
| - do/while |
| |
| Control structures for code flow are: |
| |
| - if/elseif/else |
| |
| - switch/case |
| |
| - include |
| |
| Executes the external template file and appends the output of it to the |
| current text output. |
| |
| - embed |
| |
| Inlines the code from the external template as if it was local code. The code |
| will have access to all the variables of the current stack. |
| |
| - return/stop ? |
| |
| - break |
| |
| Breaks out of loops. |
| Used outside a loop will cause an exception. |
| |
| - continue |
| |
| Continues to next iteration in loop and processes the sequence. |
| Used outside a loop will cause an exception. |
| |
| - skip |
| |
| Continues to next iteration in loop and does not process the sequence. |
| Used outside a loop will cause an exception. |
| |
| - delimiter |
| |
| Piece of code which is executed at given iterations, e.g. every other |
| iteration. |
| Used outside a loop will cause an exception. |
| |
| - once |
| |
| Execute child elements only once. |
| |
| Other structures: |
| |
| - def, undef |
| |
| - set |
| |
| |
| Counters |
| ```````` |
| .. Note: These entries are only a suggestion. |
| |
| - counter |
| |
| Starts a counter at a given value which is increased at given steps. The |
| counter can be output and increased automatically. Also counters can be |
| stacked to start sub counts for a given period and then continue on the |
| previous count later on, the current counter stack level is also available |
| for output (starts at 1). If you need multiple separate counters the *name* |
| parameter can be used or it can be assigned an object. |
| |
| Syntax:: |
| |
| {counter start [$start] [step $step] [name $name | as $object]} |
| {counter stop [name $name | $object]} |
| {counter [name $name]} |
| {counter level [name $name]} |
| |
| Counting from 0:: |
| |
| {counter start 0} |
| {counter} |
| {counter} |
| {counter stop 0} |
| |
| Counting from 1 and intervals of 2:: |
| |
| {counter start 1 step 2} |
| {counter} |
| {counter} |
| {counter stop} |
| |
| Counting headers:: |
| |
| {counter start 1} |
| <h{counter level}>{counter} Header</h{counter level}> |
| ... |
| <h{counter level}>{counter} Header</h{counter level}> |
| {counter start 1} |
| <h{counter level}>{counter} Header</h{counter level}> |
| ... |
| <h{counter level}>{counter} Header</h{counter level}> |
| |
| Using objects:: |
| |
| {counter start 1 as $c} |
| {$c.value} |
| {$c.level} |
| {counter stop $c} |
| |
| - sequence |
| |
| Similar to *counter* but will go trough a given sequence array over and over |
| again. |
| |
| Syntax:: |
| |
| {sequence start array() [name $name | as $object]} |
| {sequence stop [name $name | $object]} |
| {sequence restart [name $name]} |
| {sequence [name $name]} |
| {sequence level [name $name]} |
| |
| Sequences are typically used to generate tables with even/odd colors:: |
| |
| {sequence start array( 'red', 'blue' )} |
| <table> |
| <tr class="{sequence}">...</tr> |
| <tr class="{sequence}">...</tr> |
| <tr class="{sequence}">...</tr> |
| <tr class="{sequence}">...</tr> |
| {sequence stop} |
| |
| Using objects:: |
| |
| {sequence start 1 as $s} |
| {$s.value} |
| {$s.level} |
| {sequence stop $s} |
| |
| Output handling |
| --------------- |
| |
| Output handling is done by append the text result to the current execution |
| object. Washing of the output depends on the current output context, for |
| instance it can add additional HTML entity escaping. |
| Since some strings from functions or properties might return HTML it needs |
| ways to detect this and disable output washing. |
| |
| Note: The output from print, echo can be caught if it is desired, e.g. when |
| executing external PHP scripts. |
| |
| .. figure:: template_context.png |
| |
| The default context classes and the interface. |
| |
| Type hinting |
| ------------ |
| |
| It must be possible to give type hints to the template system for the variables |
| and parameters. This can be used by the optimizer to further optimize usage on |
| variables, e.g. operator usage and function calls. |
| |
| Op-Codes |
| -------- |
| |
| The Op-Codes are the result from the transformation of template elements. These |
| Op-Codes reflect the basic building blocks of PHP code and is highly structured |
| which allows for easy traversal and transformation. |
| The Op-Codes can be optimized to reduce the code needed for one template and |
| then generated into PHP code as text. |
| |
| The Op-Code structure will be cached on disk before elements are inlined and |
| the Op-Codes are optimized. This means that the source code for one inlined |
| element can be updated by recreating the Op-Code structure for this element and |
| then inlining and optimizing it again. |
| |
| Design keys |
| ----------- |
| |
| All PHP objects can return information on design keys to use by implementing |
| the ezcTemplateDesignkey interface. The object must return a hash array with |
| the key names and values. A value is either a string or an array of strings. |
| |
| These design keys are used to determine which actual template file to fetch |
| (only for some resources). |
| |
| Design keys are stacked for templates and subtemplates, this means that they |
| will be inherited to sub-includes unless they are overriden. Once an include is |
| finished the old design keys are restored. |
| |
| Execution |
| --------- |
| |
| The execution of a template file consists of several steps many which can |
| shortcut under some conditions. The end result is always the execution of a |
| generated PHP file which consists of code made from the template. |
| |
| .. figure:: template_execution.png |
| |
| Activities in executing a template. |
| |
| Loading contents |
| ^^^^^^^^^^^^^^^^ |
| |
| .. figure:: template_execution_content_load.png |
| |
| Loading the template contents as plain text into source. |
| |
| Transforming elements |
| ^^^^^^^^^^^^^^^^^^^^^ |
| |
| .. figure:: template_execution_element_transformation.png |
| |
| Turning elements into PHP structures. |
| |
| Generating code |
| ^^^^^^^^^^^^^^^ |
| |
| .. figure:: template_execution_generate_php.png |
| |
| Generating PHP code. |
| |
| Variables |
| --------- |
| |
| All template variables will be created as normal PHP variables in the compiled |
| code. This greatly increases the speed of the execution and makes the system |
| easier to debug. The name of the PHP variable will not match the template name, |
| the major reason being that some reserved names might clash with the user |
| defined ones. |
| |
| Reserved variables |
| ^^^^^^^^^^^^^^^^^^ |
| |
| The template system will use some PHP variables for keeping track of execution |
| states, these variables must be registered in the template system as being |
| reserved and used by the variable name generator. |
| |
| |
| Main classes |
| ------------ |
| |
| .. figure:: template.png |
| |
| Main classes for the template engine. |
| |
| Public classes |
| -------------- |
| |
| To make it easier for 3rd party developers to access or enhance the template |
| engine they must make sure they only relate to what is defined as public |
| classes. |
| |
| .. figure:: template_public.png |
| |
| Publicly available classes. |
| |
| Normal usage |
| ^^^^^^^^^^^^ |
| |
| The most common way to use the template engine is to execute template files and |
| get the resulting output text. This involves creating an *ezcTemplate* object |
| and setting the correct output context. |
| |
| Extending the engine |
| ^^^^^^^^^^^^^^^^^^^^ |
| |
| There are many ways to extend what the engine is capable of. This can be to |
| generate a new context for handling the output, creating new elements |
| (e.g. functions). |
| |
| Guidelines |
| ========== |
| |
| |
| Algorithms |
| ========== |
| |
| |
| Data structures |
| =============== |
| |
| .. figure:: template_structures.png |
| |
| The various internal classes used to execute code. |
| |
| |
| |
| .. |
| Local Variables: |
| mode: rst |
| fill-column: 79 |
| End: |
| vim: et syn=rst tw=79 |