Use ternary operator in freemarker?

后端 未结 5 900
忘了有多久
忘了有多久 2021-02-01 12:54

I just want to do something like this:


相关标签:
5条回答
  • 2021-02-01 13:16

    If you're using freemarker 2.3.23 or newer, you can use the then built-in:

    <a href="${a?then('a.htm','b.html')}" target="${openTarget}">
    

    If you're using an older version of freemarker, you can use instead the string built-in:

    <a href="${a?string('a.htm','b.html')}" target="${openTarget}">
    

    When applied to a boolean, the string built-in will act as a ternary operator.


    0 讨论(0)
  • 2021-02-01 13:28

    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).

    0 讨论(0)
  • 2021-02-01 13:33

    Using Interpolation syntax:

    "${(a?has_content)?string('a.htm','b.htm')}"
    

    has_content : can be used to handle STRING (returns FALSE in case of empty string)

    0 讨论(0)
  • 2021-02-01 13:38

    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.

    0 讨论(0)
  • 2021-02-01 13:40

    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:

    <#assign targetUrl=if(a, 'a.htm', 'b.htm')/>
    <a href="${targetUrl}">link 1</a>
    ...
    <a href="${targetUrl}">link 2</a>
    

    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>
    
    0 讨论(0)
提交回复
热议问题