Use ternary operator in freemarker?

做~自己de王妃 提交于 2019-12-03 06:28:57

问题


I just want to do something like this:

<a href="${ a? 'a.htm' : 'b.htm'}">

回答1:


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.





回答2:


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.




回答3:


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




回答4:


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>



回答5:


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)



来源:https://stackoverflow.com/questions/17539686/use-ternary-operator-in-freemarker

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!