Namespaces
Every template variable lives in a namespace, a name such as '' (the top of the page), box or Outer:Inner. The
engine stores variables as $this->Variables[<namespace>][<name>] (lib/eztemplate/classes/eztemplate.php), and every
template is processed with two namespaces at hand: the root namespace of the file and the current namespace,
which a section or let with a name can change inside the file. Namespaces are what keeps the variables of included
templates and nested loops from overwriting each other.
Contents
- Four ways to name a variable
- include without and with a name
- Namespaces made by section and let
- A variable in the wrong namespace
- Practical rules
- Related pages
Four ways to name a variable
The variable parser (variableEndPos() in lib/eztemplate/classes/eztemplateelementparser.php) reads an optional
scope sign, any number of name: prefixes and the variable name. elementValue() in eztemplate.php then finds the
namespace:
| Written | Scope | Namespace looked up |
|---|---|---|
$title | local | the root namespace of the file |
$box:title | local | root namespace + :box (or box at the top) |
$:title | relative | the current namespace |
$#title | global | exactly the namespace written, here '', the top of the page |
$#box:title | global | exactly box |
At the top of a page all of these are the same namespace ''. They differ inside included templates, sections and
let blocks.
include without and with a name
eZTemplateIncludeFunction::process() decides the namespace of the included file:
- Without
name, the file runs in the caller's current namespace. It sees every variable of the caller, and the parameters it is given are set in that namespace for the time of the include. - With
name='box', the file runs in the namespacebox(or<current>:box). Its$titlemeansbox:title, so it sees only its parameters; the caller's variables are still reachable with$#name.
This file is included twice below:
title=[$title] local=[if is_set( $node )$node.nameelseno $node/if] global=[$#node.name] relative=[$:title]Without a name it sees $node of the caller:
def $node = fetch( 'content', 'node', hash( 'node_id', 89 ) )
include uri='file:var/tmp/examples/tl-ns/parts/show.tpl' title='A'Output:
title=[A] local=[Fit & Healthy] global=[Fit & Healthy] relative=[A]With name='box' the local $node is missing, the global $#node.name still works, and the parameter $title is
removed again after the include:
def $node = fetch( 'content', 'node', hash( 'node_id', 89 ) )
include uri='file:var/tmp/examples/tl-ns/parts/show.tpl' title='B' name='box'
after: [if is_set( $title )title leakedelseno $title here/if]Output:
title=[B] local=[no $node] global=[Fit & Healthy] relative=[B]
after: [no $title here]Both forms appear in shipped designs. Without a name is convenient but couples the part to its callers; a name makes the part self-contained.
Namespaces made by section and let
section with name= processes its body in the namespace <current>:<name> and sets item, key, index,
number (and sequence) there (eZTemplateSectionFunction::process()). Nested sections nest the names, and $:item
always means the innermost:
section name=Outer loop=array( 'x', 'y' )section name=Inner loop=array( 1, 2 )[$Outer:item$Outer:Inner:item|$:item]/section/sectionOutput:
[x1|1][x2|2][y1|1][y2|2]let and default with name= do the same for their variables:
let name=Box width=3[$Box:width] [$:width]/letOutput:
[3] [3]foreach, for, while and def do not create namespaces; their variables are ordinary variables of the file.
A variable in the wrong namespace
A lookup that misses names the namespace it searched, which tells you whether the variable is missing or only out of reach:
def $title = 'root'
[$Box:title]Output:
[]Logged by the template engine:
ERROR : Unknown template variable 'title' in namespace 'Box'Practical rules
- In new templates use
defandforeach; they need no namespaces at all. - Give a reusable part a
namewhen you include it, and pass everything it needs as parameters. - Reach for
$#varonly to read page-wide values from inside a named part; to pass values up, see set with a scope. - When reading old templates,
$Name:itemis asectionorletnamespace: see Sections versus foreach.
Related pages
- Previous: Variables in depth
- Next: Attribute access
- Include
- Section (legacy)
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.