java - parameter - operator freemarker
¿Usar operador ternario en freemarker? (4)
Solo quiero hacer algo como esto:
<a href="${ a? ''a.htm'' : ''b.htm''}">
A partir de FreeMarker 2.3.23, puede escribir a?then(''a.htm'', ''b.htm'')
Then a?then(''a.htm'', ''b.htm'')
. La ventaja de la condition?then(whenTrue, whenFalse)
over condition?string(whenTrue, whenFalse)
es que funciona para non-string whenTrue
y whenFalse
, y que solo evalúa una de las expresiones whenTrue
y whenFalse
(cualquiera que sea la rama elegida).
Esta macro proporciona una forma más directa de hacer operaciones ternarias:
<#macro if if then else=""><#if if>${then}<#else>${else}</#if></#macro>
Es fácil de usar y se ve bien y bastante legible:
<@if someBoolean "yes" "no"/>
Tenga en cuenta que es @if
- y no #if
como en la directiva incorporada. Aquí hay algunos ejemplos más.
<!-- `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>
Por alguna razón, no puede agregar paréntesis alrededor de parámetros sin nombre, si no son expresiones booleanas. Eso podría haber aumentado la legibilidad aún más.
Puede definir una función personalizada if
así se declara:
<#function if cond then else="">
<#if cond>
<#return then>
<#else>
<#return else>
</#if>
</#function>
La función se puede usar en cualquier expresión ${...}
. Tu código se vería así:
<a href="${if(a, ''a.htm'', ''b.htm'')}">
A diferencia de @kapep, creo que deberías usar una función, no una macro. Las macros producen resultados (textuales), mientras que las funciones devuelven un valor que, por ejemplo, se puede asignar a una variable, pero también se escribe en la salida, por lo que usar una función es más flexible. Además, la forma de aplicar la función es mucho más cercana al uso de un operador ternario, que también se usaría dentro de expresiones ${...}
, no como una directiva.
Por ejemplo, si necesita el destino del enlace condicional varias veces, tendría sentido asignarlo a una variable local:
<#assign targetUrl=if(a, ''a.htm'', ''b.htm'')/>
<a href="${targetUrl}">link 1</a>
...
<a href="${targetUrl}">link 2</a>
Usando la función en lugar de la macro, los ejemplos de @ kapep se verían así:
<!-- `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>
Si está utilizando freemarker 2.3.23 o más reciente, puede usar el integrado then
:
<a href="${a?then(''a.htm'',''b.html'')}" target="${openTarget}">
Si está usando una versión anterior de freemarker, puede usar la string
incorporada:
<a href="${a?string(''a.htm'',''b.html'')}" target="${openTarget}">
Cuando se aplica a un booleano, la string
incorporada actuará como un operador ternario.