I'm not finding a function to test for the existence of a value in the ISML template code. There's 'isDefined' but not 'isNull'.
isDefined returns true on null values:
<isset name="woot" value="" scope="request">
<isif condition="#isDefined(woot)#">
<h1>woot</h1>
</isif>
For now I'm using:
<isif condition="#woot EQ null#">
or
<isif condition="#woot EQ ''#">
I don't know if this will work for Boolean values.
isDefined is how you would check for a null value. In AbstractTemplate you have the method isDefined(Object anObject) that is called. Checkout the compiled jsp and java versions of your isml template.
In AbstractTemplate
The code in your example is a bit misleading, it doesn't actually test for a null reference. Bear with me.
First statement :
Compiles to :
This just sets the woot variable to an empty string. If you add the following scriptlet to your isml you will see that it really isn't a null.
Disclaimer: don't use scriptlets in production code, this is only for demonstrating a point
Second line:
Evaluates if the variable exist and it does. It has an empty string as a value, not null like you might think.
So what happens here then?
Looking at the compiled version:
The
context.getFormattedValue(getObject("null"),null)
is the important bit here. It tries to retreive the variable called null, it doesnt exist so returns null. The getFormattedValue method then returns an empty string for the null argument (see TemplateExecutionConfig::getFormattedValue). The whole statement then evals to true. Not because woot is null, but because you are comparing it to a variable that doesnt exist, so you are inadvertently evaluating two empty strings. This behaviour is consistent with the EQ operator because it is use to compare strings.You would get the same result if u would use this statement too.
The third statement compares the woot variable to an empty string value, which returns true.
Compiled version:
So the real problem is that woot doesn't have the literal value null. See the following code:
I'm abusing the fact that
IDontExitPrettySureAboutThat
doesn't exist to set a null value to foo. isDefined then starts to work like you would expect. That is until someone initializes my variable to something other than null.I wouldn't advocate that you use this method, however. I think the best advice is not to use null to represent a missing value or invalid state. This thread goes into some details on this topic.