These are the built-ins that don't care (much) about the type of their left hand argument.
switch
This built-in exists since FreeMarker 2.3.23.
This is basically the in-line (expression) version of the
switch-case-default
directives. Its generic format is like
matchedValue?switch(case1,
result1,
case2,
result2, ...
caseN,
resultN,
defaultResult), where
defaultResult can be
omitted. Example:
<#list ['r', 'w', 'x', 's'] as flag>
${flag?switch('r', 'readable', 'w' 'writable', 'x', 'executable', 'unknown flag: ' + flag)}
</#list> readable writable executable unknown flag: s
That is, switch will find the first
case parameter (left
to right) whose value equals to
matchedValue, then it
returns the value of the
result parameter
that's directly after that
case parameter. If it
doesn't find an equal
case, then it will
return the value of the
defaultResult, or if
there's no
defaultResult
parameter (i.e., if the number of parameters is even) then it stops
the template processing with error.
Further details:
-
The comparison of
matchedValueto thecaseparameter value behaves exactly like the==operator. Hence it only compares scalars and only same-type values. Thus, something likex?switch(1, "r1", "c2", "r2")doesn't make sense, as ifxis non-numerical then the first case will cause error, and ifxis numerical then the second case will cause error (unlessxis1, as then we won't do further comparisons after the first one). -
Unlike with normal method calls, only those parameters of
switch(...)are evaluated that are indeed needed. For example, intwo()?switch(c1(), r1(), c2(), r2(), c3(), r3()), iftwo()returns2,c1()returns1, andc2()returns2, then only the following functions will be called, and in this order:m(),c1(),c2(),r2(). (Naturally, arguments that aren't evaluated can refer to missing variables without causing error.) It's guaranteed that thecaseparameter expressions are evaluated left to right, and only until the first match was found. It's also guaranteed that only theresultexpression that belongs to the first matchingcasewill be evaluated. It's also guaranteed that thedefaultResultexpression will only be evaluated if there was no matchingcaseparameter. -
The
caseparameter expressions need not be constant values, they can be arbitrary complex expressions. Of course, the same goes for and theresult,defaultResult, andmatchedValue. -
There's no restriction regarding the type of the
caseparameter values, like they can be strings, or numbers, or dates, etc. However, because of how the==operator works, it doesn't make sense to usecaseparameters of different types inside the sameswitch(see earlier why). -
Unlike with the
casedirective, there's no fall-through behavior there, that is, there's no need for an equivalent of thebreakdirective.
If you need to switch by a boolean value, you should use the
then
built-in instead, like
matchedBoolean?then(whenTrue,
whenFalse).
If you need to do arbitrary logical tests instead of simple
equality comparisons at the
case parameters, you
can do something like this (here we tests for ranges):
true?switch(priority <= 1, "low", priority == 2,
"medium", priority >= 3, "high")
