-
Variables need to be defined. Referring to an undefined variable is an
error in FreeMarker (i.e. it does not return an empty string as in bash or
in makefiles).
-
Default values should be specified in
template.properties
, not in the XSWT forms.
You should not define them in the XSWT page by pre-filling the corresponding
widget (e.g. <text x:id="n" text="100">
). If you specify the value in a page,
the assignment will not take effect if the user skips that page (i.e. clicks
Finish earlier). That causes the variable to remain undefined, resulting in a
runtime error during template processing.
-
Type mismatch. Variables have types in FreeMarker and one can get type conversion
errors if the templates are not programmed carefully. For example, comparing a number
and a string is a runtime error. A more serious problem is that widgets in wizard pages may implicitly
perform type conversion. For example, a
numHosts=100
line in template.properties
defines a number, but if you have a <text x:id="numHosts"/>
widget in the form,
the variable will come back from it as a string. Even worse, whether the
number->string conversion takes place will depend on whether the page gets
displayed in the wizard session. Therefore, it is recommended that
you explicitly convert numeric variables to numbers at the top of templates
(e.g. <#assign numHosts = numHosts?number>
).
-
For some reason, FreeMarker refuses to print boolean variables (e.g.
${isFoo}
results in a runtime error). The common workaround is to write
<#if isFoo>true<#else>false</#if>
; this can be shortened with our iif() function:
${iff(isFoo, "true", "false")}
.
-
Many string operations are available both as built-in FreeMarker operators
(
varname?trim
) and as Java methods via FreeMarker’s BeanWrapper (varname.trim()
).
If you are mixing the two, it is possible that you will start getting
spurious errors for the Java method calls. In that case, simply change
Java method calls to FreeMarker built-ins.
-
Some Java functionality (the instance of operator,
Class.newInstance()
, etc.)
cannot be accessed via BeanWrapper. If you hit such a limitation, check
our LangUtils
class that provides FreeMarker-callable static methods
to plug these holes.