In most templates, I find it good practice, to start by collecting data (using variable initializations), followed by defining how this data is presented to the user. A typical statement during data collection is declaring a variable based on a condition. For example, I would like to initialize a variable filter, based on a variable prefix being empty or not. I could use:

var filter := "@%"
if(prefix != "") {
   filter := ""
}

Unfortunately, this does not work, as assignments are not allowed in pages (I guess that makes sense). Another option would be:

var filter := 
   if(prefix != "") { "" } else { "@%" }

Yet, this is also not allowed by syntax. Therefore, I reside to:

if(prefix != "") {
   var filter := ""
} else {
   var filter := "@%"
}

This is rather ugly, due to a duplicate variable definition and may be rather shaky due to scoping rules. However, it is allowed and I would kind of expect it to work (or give an error). Unfortunately, when I run this, the condition is ignored and I always get a "@%" assigned to filter. Even though this is a strange statement, this is not the behavior I would expect. I guess it is a bug.

I figured out that I can get it to work by extracting the statements into a function:

function tagSuggestionFilter(tagPrefix : String) : String {
   if(tagPrefix != "") {
      return "";
   }
   return "@%";
}
Submitted by Sander Vermolen on 9 March 2010 at 14:45

On 9 March 2010 at 15:19 Danny Groenewegen commented:

Coincidentally, I was just working on a constraint for this, template vars (also init, action, define) will no longer allowed to be nested in other template elements and must be declared at top level in the define. This check will avoid confusion until support for such nested elements is added.

Instead of a function you can also use an init block:

var filter := "@%"
init{
  if(prefix != "") {
    var filter := ""
  }
}

On 9 March 2010 at 15:58 Sander Vermolen commented:

Great. However, using init blocks does not work for me. I have:

define ajax tagSuggestions(tagPrefix : String, i : Issue) {
   var tagFilter := "@%";
   init {
      if(tagPrefix != "") {
         tagFilter := "";
      }
   }
   ... usage of tagFilter ...
   ... presentation of data ...
}

which is syntax correct. Unfortunately, this always causes tagFilter to be assigned "@%". It therefore appears to show similar behavior to not using an init block.


On 9 March 2010 at 16:08 Danny Groenewegen commented:

In the webdsl.org app I use this pattern, but only the properties of the var are assigned to, looks like a pass-by-value vs pass-by-reference bug in the implementation of init blocks.


On 10 March 2010 at 10:17 Sander Vermolen commented:

We (Danny & Sander) tried reproducing this issue using Danny’s latest WebDSL version, but failed. We will therefore assume it is fixed in the trunk.

Log in to post comments