在freemarker中使用三元运算符?

Posted

技术标签:

【中文标题】在freemarker中使用三元运算符?【英文标题】:Use ternary operator in freemarker? 【发布时间】:2013-07-06 13:20:06 【问题描述】:

我只想做这样的事情:

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

【问题讨论】:

试试 var url=(a?a.htm:b.htm).......跨度> 正如obourgain下面所说,你可以使用?string,但a的值究竟是什么?你想测试它是否存在,或者它是否是布尔值true 【参考方案1】:

如果您使用的是 freemarker 2.3.23 或更新版本,您可以使用内置的then

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

如果您使用的是旧版本的 freemarker,您可以改用内置的 string

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

当应用于布尔值时,string 内置函数将充当三元运算符。


【讨论】:

乍一看,这并不是很明显。我赞成这个答案,但老实说,只做一个&lt;#if&gt;&lt;#else&gt; 可能更具可读性 它不是很可读,因为这不是它的预期用途。它用于格式化布尔值,例如Registered: $registered?string('yes', 'no')。自 2.3.23 起,condition?then(whenTrue, whenFalse) 用于此。 @ddekany 感谢您提供信息,我更新了答案以包含新的解决方案。【参考方案2】:

如果您使用的是 2.3.23 之前的旧 Freemarker 版本,那么您可以使用这个宏,它提供了一种简单的方式来执行三元运算:

<#macro if if then else=""><#if if>$then<#else>$else</#if></#macro>

它易于使用,看起来不错且可读性强:

<@if someBoolean "yes" "no"/>

请注意,它是@if - 而不是#if,如内置指令中那样。这里还有一些例子。

<!-- `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> 

由于某些原因,如果它们是非布尔表达式,则不能在无名参数周围添加括号。这本可以进一步提高可读性。

【讨论】:

【参考方案3】:

您可以定义一个自定义函数if,声明如下:

<#function if cond then else="">
  <#if cond>
    <#return then>
  <#else>
    <#return else>
  </#if>
</#function>

该函数可用于任何$... 表达式。您的代码如下所示:

<a href="$if(a, 'a.htm', 'b.htm')">

与@kapep 相比,我认为您应该使用函数,而不是宏。 宏产生(文本)输出,而函数返回一个值,例如可以分配给变量,但也可以写入输出,因此使用函数更加灵活。此外,应用函数的方式更接近于使用三元运算符,也可以在 $... 表达式中使用,而不是作为指令。

例如,如果您多次需要条件链接目标,则将其分配给局部变量是有意义的:

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

使用函数而不是宏,@kapep 的示例如下所示:

<!-- `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>

【讨论】:

【参考方案4】:

从 FreeMarker 2.3.23 开始,您可以编写 a?then('a.htm', 'b.htm')condition?then(whenTrue, whenFalse) 相对于condition?string(whenTrue, whenFalse) 的优势在于它适用于非字符串whenTruewhenFalse,并且它只计算whenTruewhenFalse 表达式之一(无论选择哪个分支)。

【讨论】:

【参考方案5】:

使用插值语法:

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

has_content : 可用于处理 STRING(如果为空字符串则返回 FALSE)

【讨论】:

以上是关于在freemarker中使用三元运算符?的主要内容,如果未能解决你的问题,请参考以下文章

Yaml 中的三元运算符

如何在三元条件运算符中使用 Optional 变量?

如何在 VueJs 中使用三元运算符

专业词汇-数学-运算:三元运算符

React useState:如何将三元运算符放在三元运算符中?

在视图中使用三元运算符