Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

Variables in depth

The exact rules of def, undef, set, let and default from eZTemplateDefFunction and eZTemplateSetFunction - the warnings for defining twice, setting an unknown variable and undefining one that def did not make, undef…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/help/template-language/variables-in-depth.md

On this page

Variables in depth

Variables and def shows how to use variables. This page gives the exact rules, read from lib/eztemplate/classes/eztemplatedeffunction.php and lib/eztemplate/classes/eztemplatesetfunction.php, and shows each case on a development installation, including the warnings the engine writes.

Contents

  1. The five functions
  2. def, set, undef
  3. def on a variable that exists
  4. set on a variable that does not exist
  5. undef with and without names
  6. let and default: variables for a block
  7. Lifetime: a variable belongs to its file
  8. set with a scope
  9. Related pages

The five functions

FunctionClassCreatesChangesNotes
defeZTemplateDefFunctionyesonly with a warningvariable lives until the end of the file or undef
undefeZTemplateDefFunctionremovesonly variables made with def; no names: all of them
seteZTemplateSetFunctionno, warnsyestakes scope and name
leteZTemplateSetFunctionyes, for its blockremoves what it made at {/let}
defaulteZTemplateSetFunctiononly if missing, for its blockkeeps an existing value

The dollar sign in front of a name is optional for all of them ({def x=1} works); the parser skips it.

def, set, undef

Several variables can be handled in one tag:

{def $count = 1 $label = 'items'}
[{$count} {$label}]
{set $count = $count|inc $label = 'things'}
[{$count} {$label}]
{undef $label}
[{if is_set( $label )}label still set{else}label removed{/if}] [{$count}]

Output:

[1 items][2 things][label removed] [2]

def on a variable that exists

process() checks hasVariable() first. If the variable exists, it writes the warning "Variable '...' is already defined." and assigns the new value anyway:

{def $color = 'red'}
{def $color = 'blue'}
[{$color}]

Output:

[blue]

Logged by the template engine:

WARNING def: Variable 'color' is already defined.

So a repeated {def} is not fatal, but the warning means the template has two definitions where it wanted one, or a variable leaks in from an including template.

set on a variable that does not exist

set changes existing variables only. For an unknown name it writes "Variable '...' doesn't exist, cannot set" and does nothing:

{set $size = 'large'}
[{if is_set( $size )}size exists{else}size was not created{/if}]

Output:

[size was not created]

Logged by the template engine:

WARNING set: Variable 'size' doesn't exist, cannot set

undef with and without names

{undef $a $b} removes the named variables, but only those made with {def} in the current file (hasLocalVariable()); for any other name it warns "Variable '...' is not defined with {def}." and leaves it. Since the 3.8 fix recorded in the changelog, undef cannot remove variables it did not create. Without names, {undef} removes every variable the current file defined with def (unsetLocalVariables()):

{def $a = 1 $b = 2 $c = 3}
{undef}
[{if is_set( $a )}a{/if}{if is_set( $b )}b{/if}{if is_set( $c )}c{/if}] all removed

Output:

[] all removed
{undef $never_defined}
done

Output:

done

Logged by the template engine:

WARNING undef: Variable 'never_defined' is not defined with {def}.

let and default: variables for a block

let and default are block functions (hasChildren() returns true for them). They define their variables, process the children, then remove only what they defined (cleanupVariables()). default defines a variable only when it is missing, which made it the classic way to give an included template optional parameters; first_set does the same in an expression.

{let greeting='hi'}inside let: [{$greeting}]{/let}
after let: [{if is_set( $greeting )}still set{else}gone{/if}]
{def $size = 'given'}
{default size='fallback' color='fallback'}[{$size}] [{$color}]{/default}

Output:

inside let: [hi]after let: [gone][given] [fallback]

Lifetime: a variable belongs to its file

Each template file opens its own list of local variables (createLocalVariablesList()), and when the file ends, the variables it made with def are removed. A variable defined inside an included template is therefore gone after the {include}:

{def $inner = 'made in the part'}
part: [{$inner}]
{include uri='file:var/tmp/examples/tl-vars/parts/maker.tpl'}
after: [{if is_set( $inner )}inner visible{else}inner gone after the include{/if}]

Output:

part: [made in the part]
after: [inner gone after the include]

Parameters passed to {include} are set before the file runs and removed (or restored to their old value) after it, by eZTemplateIncludeFunction::process().

set with a scope

set (and let and default) accept scope=relative, scope=root or scope=global, and name= to pick a namespace. Written without a dollar sign, scope and name are not variables but these two options (the parser renames them to -scope and -name).

ScopeNamespace usedTypical use
relative (default)the current namespaceordinary assignment
rootthe root namespace of the current template filechange a value of the file from inside a section or let
globalthe empty namespace, the top of the pagehand a value back from a template included with name=

The included file below runs in its own namespace (name='part'), so it does not see $total of the caller, but set scope=global changes the caller's variable:

{def $inner = 'made in the part'}
part sees: [{if is_set( $total )}{$total}{else}no $total{/if}]
{set scope=global total=10}
{def $total = 1}
{include uri='file:var/tmp/examples/tl-vars/parts/counter.tpl' name='part'}
after include: [{$total}] [{if is_set( $inner )}inner visible{else}inner not visible{/if}]

Output:

part sees: [no $total]after include: [10] [inner not visible]

Use this sparingly: a template that changes its caller's variables is hard to follow. To pass values to the pagelayout there is the persistent variable (The persistent variable).

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.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x