plonezopetemplate-talzpt

How does zope/plone evaluate variables?


Imagine this scenario:

I have a ZPT in Zope where I define, into a metal block, a global variable.
This variable takes its value from an expression like this

global myVar id | nothing;
global anotherVar 1;

where nothing could be replaced with python:0 or python:False or None and so on.

Now imagine that into another block, I'll do something like

global myVar2 myVar | anotherVar | nothing;

where nothing could be everything that I specified above.

Now suppose that id hasn't a value and so myVar took nothing (or the other possible values; it's makes not difference at all).
What I expected was that myVar2 took anotherVar's value, since anotherVar has a value. But with great surprise, I notice that this isn't true and myVar2 took myVar value; that means nothing.

If I understand what is happening, I'll suppose that this kind of statement only control over existence of that variable and not over it's value.

Obviously I can make that kind of statement into a pythonic way and, of course, it works "well" (namely, as I expected)
So, someone can confirm or disprove what I suppose there ?


Solution

  • What you are asking is not Plone or Zope specific, you are dealing with a TALES statement here, which, together with TAL and METAL form the page template language implemented by Zope Page Templates (and, incidentally, also by , plus several other implementations in different programming languages).

    You are using a TALES path expression when you use the | character, and it is not the same as a Python or expression. Each path named in the expression will by resolved, and only if it doesn't exist will the next path be used. From the specification:

    When a TALES path expression is evaluated, it attempts to traverse each path, from left to right, until it succeeds or runs out of paths.

    Since all your paths resolve to existing variable names, they all exist and the first one will be used, regardless of it's value.

    You want to use a python: expression instead:

    myVar2 python:myVar or anotherVar or None;
    

    Note that in TAL there rarely is a need for the global keyword. You probably want to define these items on your root element of your document instead; variables are visible within the same scope as the XML or HTML element they are defined on:

    <html tal:define="myVar id | nothing; anotherVar 1;">
      <!-- myVar and anotherVar are visible in the whole HTML document -->
    </html>