Defining TALES variables

The TAL define attribute adds a new variable definition to the current TALES context. It is in many ways like a variable definition in any programming language.

Syntax

tal:define="SCOPE NAME EXPRESSION"

Variable scope

The variable scope (SCOPE) is optional, and defaults to local if omitted. It may have one of two possible values, controlling how the variable is stored within the TALES context:

  • local indicates that the variable will be available to this element, and all of its child elements. However, sibling elements or parent elements will not have access to this variable.
  • global indicates that the variable will be available document-wide; once the ZPT renderer has rendered the current element, any subsequent element may make use of this variable definition, regardless of whether it is a child of the current element or not.

Global definitions are generally only very rarely required, as it is possible to define local variables at the root level of the document if required. The ZPT parser always operates upon a document in the order it is written, from the beginning to the end.

The variable name

Permitted variable names (NAME) are one or more non-whitespace characters. They are case sensitive and mandatory.

Note that the TALES csharp: expressions plugin is installed by default.
If this plugin is installed then tal:define variable names must also be valid C♯ variable names.

The value expression

The expression (EXPRESSION) is mandatory; it is interpreted as a TALES expression. The expression is evaluated and the result stored as the value of the variable. null values are handled normally – if the expression evaluates to null, then null is stored in the TALES context.

If the TALES expression result indicates that the action should be cancelled then no variable is created/changed. If multiple variables are defined within the same attribute and a single definition is cancelled in this way, other definitions in that attribute are unaffected and are processed normally.

Variable naming conflicts

It is permitted to define multiple variables of the same name; here is how this works:

Scopes searched

When a TALES context is used to resolve a root variable, local variables (which includes repeat variables) are searched before global variables. Thus, local variables will always hide global variables of the same name.

Identically-named local variables mask their parents

If multiple local variables are defined of the same name then TAL will use the variable which is defined upon either the current element, or the closest parent element. The same is true for tal:repeat variables. For example:

<div tal:define="foo string:One">
  <div tal:define="foo string:Two">
    <div tal:define="foo string:Three">
      The following renders as "Three"<br>
      <span tal:replace="foo">Foo</span>
    </div>
    The following renders as "Two"<br>
    <span tal:replace="foo">Foo</span>
  </div>
  The following renders as "One"<br>
  <span tal:replace="foo">Foo</span>
</div>

Once a local variable 'goes out of scope' (outside its defining element), the next closest in-scope definition of the same name will become visible once again.

Global variables are overwritten

If a global variable definition would create a variable of the same name as an existing global variable, then the existing variable is overwritten with the new value. Once this has happened, there is no way to get the previous value.

Defining multiple variables at once

It is permitted to define multiple variables in the same tal:define attribute. Each definition is separated by a semicolon (and optional whitespace for readability):

<div tal:define="foo string:One;
                 bar Model/My/Value;
                 baz string:Three">
  Three variables all defined.
</div>

If you wish to use a semicolon character in a definition expression (for example as part of a string: TALES expression) then you must escape it by doubling-it up: ;;.