This macro provides a more straightforward way to do ternary operations:
<#macro if if then else=""><#if if>${then}<#else>${else}</#if></#macro>
It's easy to use and looks nice and quite readable:
<@if someBoolean "yes" "no"/>
Note that it is @if - and not #if as in the built-in directive. Here are some more examples.
<!-- `else` is optional -->
<@if someBoolean "someBoolean is true"/>
<!-- expressions -->
<@if (someBoolean||otherBoolean) "hello,"+user.name 1+2+3 />
<!-- with parameter names -->
<@if someBoolean then="yes" else="no" />
<!-- first in list? -->
<#list seq as x>
<@if (x_index==0) "first" "not first"/>
<#list>
For some reason you can't add parenthesis around nameless parameters, if they are non-boolean expressions. That could have increased readability even more.
You can define a custom function if that is declared like so:
<#function if cond then else="">
<#if cond>
<#return then>
<#else>
<#return else>
</#if>
</#function>
The function can be used in any ${...} expression. Your code would look like so:
<a href="${if(a, 'a.htm', 'b.htm')}">
In contrast to @kapep, I think you should use a function, not a macro.
Macros produce (textual) output, while functions return a value that can for example be assigned to a variable, but also written to the output, so using a function is more flexible. Furthermore, the way to apply the function is much closer to using a ternary operator, which would also be used inside ${...} expressions, not as a directive.
For example, if you need the conditional link target multiple times, it would make sense to assign it to a local variable:
Using the function instead of the macro, @kapep's examples would look like this:
<!-- `else` is optional -->
${if(someBoolean, "someBoolean is true")}
<!-- expressions -->
${if(someBoolean||otherBoolean, "hello,"+user.name, 1+2+3)}
<!-- with parameter names: not possible with functions,
but also not really helpful -->
<!-- first in list? -->
<#list seq as x>
${if(x_index==0, "first", "not first")}
<#list>
As of FreeMarker 2.3.23 you can write a?then('a.htm', 'b.htm'). The advantage of condition?then(whenTrue, whenFalse) over condition?string(whenTrue, whenFalse) is that it works for non-string whenTrue and whenFalse, and that it only evaluates one of whenTrue and whenFalse expressions (whichever branch is chosen).
This macro provides a more straightforward way to do ternary operations:
It's easy to use and looks nice and quite readable:
Note that it is
@if
- and not#if
as in the built-in directive. Here are some more examples.For some reason you can't add parenthesis around nameless parameters, if they are non-boolean expressions. That could have increased readability even more.
You can define a custom function
if
that is declared like so:The function can be used in any
${...}
expression. Your code would look like so:In contrast to @kapep, I think you should use a function, not a macro. Macros produce (textual) output, while functions return a value that can for example be assigned to a variable, but also written to the output, so using a function is more flexible. Furthermore, the way to apply the function is much closer to using a ternary operator, which would also be used inside
${...}
expressions, not as a directive.For example, if you need the conditional link target multiple times, it would make sense to assign it to a local variable:
Using the function instead of the macro, @kapep's examples would look like this:
If you're using freemarker 2.3.23 or newer, you can use the
then
built-in:If you're using an older version of freemarker, you can use instead the
string
built-in:When applied to a boolean, the
string
built-in will act as a ternary operator.As of FreeMarker 2.3.23 you can write
a?then('a.htm', 'b.htm')
. The advantage ofcondition?then(whenTrue, whenFalse)
overcondition?string(whenTrue, whenFalse)
is that it works for non-stringwhenTrue
andwhenFalse
, and that it only evaluates one ofwhenTrue
andwhenFalse
expressions (whichever branch is chosen).