我只想做这样的事情:
<a href="${ a? 'a.htm' : 'b.htm'}">
答案 0 :(得分:70)
如果您使用的是免费标记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
内置函数将充当三元运算符。
答案 1 :(得分:6)
这个宏提供了一种更简单的三元运算方式:
<#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>
出于某种原因,如果它们是非布尔表达式,则无法在无名参数周围添加括号。这可能会提高可读性。
答案 2 :(得分:3)
从FreeMarker 2.3.23开始,您可以编写a?then('a.htm', 'b.htm')
。 condition?then(whenTrue, whenFalse)
优于condition?string(whenTrue, whenFalse)
的优势在于它适用于非字符串whenTrue
和whenFalse
,并且它仅评估whenTrue
和{{1}中的一个表达式(选择哪个分支)。
答案 3 :(得分:2)
您可以定义一个声明如下的自定义函数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 :(得分:0)
使用插值语法:
“ $ {(a?has_content)?string('a.htm','b.htm')}”
has_content:可用于处理STRING(如果为空字符串,则返回FALSE)