Подтвердить что ты не робот

Использовать тройной оператор в freemarker?

Я просто хочу сделать это вот так:

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

С уважением.

4b9b3361

Ответ 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 будет действовать как тернарный оператор.


Ответ 2

Этот макрос предоставляет более простой способ сделать тройные операции:

<#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

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

Ответ 4

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