2013-07-09 9 views

risposta

49

Se stai usando freemarker 2.3.23 o più recente, è possibile utilizzare la then built-in:

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

Se si utilizza una versione precedente di freemarker, è possibile utilizzare invece il string built -in:

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

Quando applicata a un booleano, il string incorporato agirà come operatore ternario.


+4

A prima vista non è proprio ovvio cosa stia facendo. Ho svettato la risposta, ma onestamente potrebbe essere più leggibile semplicemente fare un '<#if>' e '<#else>' –

+0

Non è molto leggibile in quanto questo non è l'uso previsto di esso. È per la formattazione di valori booleani, come 'Registered: $ {registered? String ('yes', 'no')}'. A partire da 2.3.23 c'è 'condition? Then (whenTrue, whenFalse)' per questo. – ddekany

+0

@ddekany Grazie per l'informazione, ho aggiornato la risposta per includere la nuova soluzione. – obourgain

6

Questa macro fornisce un modo più semplice per fare operazioni ternari:

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

E 'facile da usare e sembra bello e abbastanza leggibile:

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

Si noti che è @if - e non #if come nella direttiva integrata. Ecco alcuni altri esempi.

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

Per qualche motivo non è possibile aggiungere parentesi attorno parametri senza nome, se sono espressioni non booleane. Ciò potrebbe aumentare la leggibilità ancora di più.

1

È possibile definire una funzione personalizzata if che viene dichiarata in questo modo:

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

La funzione può essere utilizzata in qualsiasi ${...} espressione. Il tuo codice sarà simile al seguente:

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

Al contrario di @kapep, penso che dovresti usare una funzione, non una macro. I macro producono output (testuali), mentre le funzioni restituiscono un valore che può essere assegnato ad esempio ad una variabile, ma anche scritto sull'output, quindi l'uso di una funzione è più flessibile. Inoltre, il modo di applicare la funzione è molto più vicino all'utilizzo di un operatore ternario, che verrebbe utilizzato anche nelle espressioni ${...}, non come direttiva.

Per esempio, se avete bisogno la destinazione del collegamento condizionale più volte, avrebbe senso per assegnarlo a una variabile locale:

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

Usando la funzione al posto della macro, esempi di @ kapep sarà simile questo:

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

A partire da FreeMarker 2.3.23 è possibile scrivere a?then('a.htm', 'b.htm'). Il vantaggio di condition?then(whenTrue, whenFalse) su condition?string(whenTrue, whenFalse) è che funziona per non stringa whenTrue e whenFalse e che valuta solo una delle espressioni whenTrue e whenFalse (qualunque sia il ramo scelto).