Hi,

I added the solutions mentioned in the previous mails to the proposal. Here 
are the new solutions and a new evaluation. Please, check if it is correct. 

The "context" proposal is not included. Frederik or Kore can you give me an 
example? Please, keep in mind that the word "context" may be confusing 
because we use that to set the target output to: HTML or text.

Attached is the proposal.

=====



Solution 6: Struct like variable passed on
------------------------------------------
The variables send to the first template can be packed in one structure. For
example the user application sends:

$t = new ezcTemplate();
$t->send->structure = new ezcTemplateVariableCollection();
$t->send->structure->a = 1;
$t->send->structure->b = 2;
$t->process("p");

Template p and q are:

Template p:
{use $structure}
{include "q" send $structure}


Template q:
{use $structure}
{$structure->a}
{$structure->b}




Solution 7: Provide a variable with all send variables
------------------------------------------------------
Almost the same as solution 6, but a struct like variable with all 'send' 
variables is provided by default. 

User application:
$t = new ezcTemplate();
$t->send->a = 1;
$t->send->b = 2;
$t->process("p");


Template p:
{use $send, $a}
{$a}
{include "q" send $send}


Template q:
{use $send}
{$send->a}
{$send->b}


It can also be that the $send variable is always available for all templates.
The templates would be:

Template p:
{use $a}
{$a}
{include "q"}


Template q:
{use $send}
{$send->a}
{$send->b}



Solution 8: Add a function that can retrieve send variables
-----------------------------------------------------------
A function, possibly a custom function, can retrieve all 'send' variables:

User application:
$t = new ezcTemplate();
$t->send->a = 1;
$t->send->b = 2;
$t->process("p");


Template p:
{use $a}
{$a}
{include "q"}


Template q:
{var $send = getSendVariables()}
{$send->a}
{$send->b}

Or:
{var $b = getSendVariable("b")}
{$b}




Evaluation
----------
Many solutions share the same concept. Therefor we categorized the solutions
in three groups:

- Group 1: Solution 1, 2 and 3.
- Group 2: Solution 4 and 5.
- Group 3: Solution 6, 7 and 8. 


Group 1 changes the behavior of the {include} statement. The changed behavior
results that the original send variables are passed along without specifying
those variables explicitly.

Group 2 adds a keyword to the included template so that more variables are 
available.

Group 3 packs all the original send variables in a group (object).


Advantages and disadvantages for group 1:

+ Easy to write a (single) template. No knowledge is needed where variables
  are made available. {use} specifies only which variables are used inside the
  template.

+ Easy to change in the template code.

+ Easy to see which variables are used in the template (and are declared 
  externally).

- Once a template is written, it may be difficult to 'backtrack' a variable to
  it's declaration. Keep in mind that when 'template overrides' are used, this
  task is difficult without extra runtime information.


Advantages and disadvantages for group 2:

+ Easy to see if a variable comes from the user application or from the
  calling template. 

+ Easy to see which variables are used in the template (and are declared 
  externally).

- Makes templates less generic. Multi-purpose templates may be called from
  anywhere. 

- May be harder to write the template when it's unknown where previous
  templates declare their variables.

- It is not possible to specify a variable that comes from the user
  application unless it's (modified and) sent by the previous template.
  (Making this work would undo the 'easy backtracking' advantage.)



Advantages and disadvantages for group 3:

+ Some variants are possible to implement without changing the template
  engine or are already available. Send-use structure is the same.

+ Easy to see if a variable comes from the user application or from the
  calling template. 

- Hard to see which variables are actually used. (The group is only
  available in the {use} block.) Also checking if a variable is set, has to be
  done manually.

- Extra code in the templates itself is needed to retrieve a variable from the
  top scope.

- Makes templates less generic. Multi-purpose templates may be called from
  anywhere. 



Problem
-------
In a system with lots of nested templates or template overrides the amount of
variables that need to be forwarded to each template may grow out of
proportion. The following example uses three templates: p, q, and r that
forward all variables via includes to the underlying template:


Template p:
{use $a, $b, $c, $d, $e, $f}
{include "q" send $a, $b, $c, $d, $e, $f}


Template q:
{use $a, $b, $c, $d, $e, $f}
Show a: {$a}
{include "r" send $b, $c, $d, $e, $f}


Template r:
{use $b, $c, $d, $e, $f}
Show all variables: {$b}, {$c}, {$d}, {$e}, {$f}


The user application sends all external variables:
$t = new ezcTemplate();
$t->send->a = 1, 
$t->send->b = 2,
...
$t->send->f = 6,
$t->process("p");



In this example, we nested the templates three deep. In real applications (eZ
publish scale) this nesting will be deeper. Another technique some
applications use are template overrides. Basically, a template override
decides dynamically what template to include and execute. An {if} block will
be used in this document to simulate a in general much complexer override 
system:

{use $load_p, $a, $b, $c, $d, $e, $f}
{if $load_p}
    {include "p" send $a, $b, $c}
{else}
    {include "q" send $d, $e, $f}
{/if}


The use-variables: a, b, c, d, e, and f are never used inside the template,
but only forwarded. 


Solution 1: ezcTemplateConfiguration option
-------------------------------------------

An option in the ezcTemplateConfiguration changes the behavior of the
{include} statements. The {include} statement will then forward all the
variables that it got from the user application by default. The modified
example will be:


Template p:
{include "q"}


Template q:
{use $a}
Show a: {$a}
{include "r"}


Template r:
{use $b, $c, $d, $e, $f}
Show all variables: {$b}, {$c}, {$d}, {$e}, {$f}


The user application remains the same:
$t = new ezcTemplate();
$t->send->a = 1, 
$t->send->b = 2,
...
$t->send->f = 6,
$t->process("p");


The {use} block specifies which variables are used directly in that template.
Where the variables come from is not important.



Solution 2: Add a keyword to include
------------------------------------

Same as solution 1, but instead of adding a configuration a special keyword is
added to the include. This triggers the new behavior. For example:

{include "q" with_externals}

or:

{var $local_var = 2}
{include "q" with_externals send $local_var}



Solution 3: Add a block simular to include
------------------------------------------

Same as solution 1, but then add a new block to ezcTemplate that works simular
to include. For example:

{extern "q"}



Solution 4: Globals
-------------------
Variables used in the template, coming directly the user application are 
specified
via the {global} keyword. For example:  


Template p:
{var $local_var = 2}
{include "q" send $local_var}


Template q:
{global $a}
{use $local_var}
Show a: {$a}
{include "r" send $local_var}


Template r:
{global $b, $c, $d, $e, $f}
{use $local_var}
Show all variables: {$b}, {$c}, {$d}, {$e}, {$f}


The user application remains the same:
$t = new ezcTemplate();
$t->send->a = 1, 
$t->send->b = 2,
...
$t->send->f = 6,
$t->process("p");



It is more verbose where a variable comes from. It may be more difficult to
write the template, because the origin of the variable may not always be known.



Solution 5: Add external keyword to {use}
-----------------------------------------

This solution adds an external keyword to the {use}, so that it could be used
like:

Template p:
{var $local_var = 2}
{include "q" send $local_var}


Template q:
{use $local_var, external $a}
Show a: {$a}
{include "r" send $local_var}


Template r:
{use $local_var, external $b, external $c, external $d, external $e, external 
$f}
Show all variables: {$b}, {$c}, {$d}, {$e}, {$f}


The user application remains the same:
$t = new ezcTemplate();
$t->send->a = 1, 
$t->send->b = 2,
...
$t->send->f = 6,
$t->process("p");



Solution 6: Struct like variable passed on
------------------------------------------
The variables send to the first template can be packed in one structure. For
example the user application sends:

$t = new ezcTemplate();
$t->send->structure = new ezcTemplateVariableCollection();
$t->send->structure->a = 1;
$t->send->structure->b = 2;
$t->process("p");

Template p and q are:

Template p:
{use $structure}
{include "q" send $structure}


Template q:
{use $structure}
{$structure->a}
{$structure->b}




Solution 7: Provide a variable with all send variables
------------------------------------------------------
Almost the same as solution 6, but a struct like variable with all 'send' 
variables is provided by default. 

User application:
$t = new ezcTemplate();
$t->send->a = 1;
$t->send->b = 2;
$t->process("p");


Template p:
{use $send, $a}
{$a}
{include "q" send $send}


Template q:
{use $send}
{$send->a}
{$send->b}


It can also be that the $send variable is always available for all templates.
The templates would be:

Template p:
{use $a}
{$a}
{include "q"}


Template q:
{use $send}
{$send->a}
{$send->b}



Solution 8: Add a function that can retrieve send variables
-----------------------------------------------------------
A function, possibly a custom function, can retrieve all 'send' variables:

User application:
$t = new ezcTemplate();
$t->send->a = 1;
$t->send->b = 2;
$t->process("p");


Template p:
{use $a}
{$a}
{include "q"}


Template q:
{var $send = getSendVariables()}
{$send->a}
{$send->b}

Or:
{var $b = getSendVariable("b")}
{$b}




Evaluation
----------
Many solutions share the same concept. Therefor we categorized the solutions
in three groups:

- Group 1: Solution 1, 2 and 3.
- Group 2: Solution 4 and 5.
- Group 3: Solution 6, 7 and 8. 


Group 1 changes the behavior of the {include} statement. The changed behavior
results that the original send variables are passed along without specifying
those variables explicitly.

Group 2 adds a keyword to the included template so that more variables are 
available.

Group 3 packs all the original send variables in a group (object).


Advantages and disadvantages for group 1:

+ Easy to write a (single) template. No knowledge is needed where variables
  are made available. {use} specifies only which variables are used inside the
  template.

+ Easy to change in the template code.

+ Easy to see which variables are used in the template (and are declared 
  externally).

- Once a template is written, it may be difficult to 'backtrack' a variable to
  it's declaration. Keep in mind that when 'template overrides' are used, this
  task is difficult without extra runtime information.


Advantages and disadvantages for group 2:

+ Easy to see if a variable comes from the user application or from the
  calling template. 

+ Easy to see which variables are used in the template (and are declared 
  externally).

- Makes templates less generic. Multi-purpose templates may be called from
  anywhere. 

- May be harder to write the template when it's unknown where previous
  templates declare their variables.

- It is not possible to specify a variable that comes from the user
  application unless it's (modified and) sent by the previous template.
  (Making this work would undo the 'easy backtracking' advantage.)



Advantages and disadvantages for group 3:

+ Some variants are possible to implement without changing the template
  engine or are already available. Send-use structure is the same.

+ Easy to see if a variable comes from the user application or from the
  calling template. 

- Hard to see which variables are actually used. (The group is only
  available in the {use} block.) Also checking if a variable is set, has to be
  done manually.

- Extra code in the templates itself is needed to retrieve a variable from the
  top scope.

- Makes templates less generic. Multi-purpose templates may be called from
  anywhere. 




-- 
Components mailing list
Components@lists.ez.no
http://lists.ez.no/mailman/listinfo/components

Reply via email to