2013-07-09 2 views
28

Я просто хочу, чтобы сделать это так:Использовать тройной оператор в freemarker?

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

С наилучшими пожеланиями.

ответ

49

Если вы используете 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 встроенных будет выступать в качестве троичного оператора.


+4

На первый взгляд это не совсем очевидно, что это такое. Я подтвердил ответ, но, честно говоря, он может быть более читаемым, чтобы просто сделать «<#if>» и «<#else>» –

+0

. Это не очень читаемо, поскольку это не намеренное его использование. Это для форматирования логических значений, таких как 'Registered: $ {registered? String ('yes', 'no')}'. Начиная с версии 2.3.23, существует условие «then» (whenTrue, whenFalse) 'для этого. – ddekany

+0

@ddekany Спасибо за информацию, я обновил ответ, чтобы включить новое решение. – obourgain

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> 

По какой-то причине вы не можете добавить скобки вокруг безымянных параметров, если они не являются булевыми выражениями. Это могло бы повысить удобочитаемость.

1

можно определить пользовательскую функцию 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> 
3

по FreeMarker 2.3.23 вы можете написать a?then('a.htm', 'b.htm'). Преимущество condition?then(whenTrue, whenFalse) по сравнению с condition?string(whenTrue, whenFalse) заключается в том, что он работает для нестрочных whenTrue и whenFalse и что он оценивает только один из выражений whenTrue и whenFalse (какая бы ни была выбрана ветка).

Смежные вопросы