2012-08-08 23 views
9

Hello freemarkers gurufunzioni FreeMarker vs macro

ho capito che la differenza tra le funzioni FreeMarker e macro è che le macro possono stampare all'uscita, ma non possono restituire valori, mentre le funzioni possono restituire valori, ma non è possibile stampare all'uscita.

Beh, sto avendo un problema, perché ho bisogno di entrambi per stampare e valori di ritorno:

sto facendo esplorazione albero ricorsivo con freemarker e quindi ho una macro chiamato recurvively. Mentre l'albero viene esplorato, ho bisogno sia di stampare le informazioni del nodo sull'output, ma anche di calcolare e restituire statistiche sui nodi esplorati (ad esempio la somma di una proprietà specifica dei nodi esplorati)

Se uso macro essendo chiamato in modo ricurvo, posso stampare le informazioni sul nodo ma non posso restituire le statistiche all'entità chiamante.

Se utilizzo una funzione chiamata ricorsivamente, posso restituire le statistiche ma non posso stampare le informazioni del nodo sull'output.

Una soluzione potrebbe essere quella di esplorare l'albero due volte, una volta per stampare le informazioni sul nodo e un'altra per raccogliere le statistiche, ma mi dispiacerebbe usare questa soluzione poco elegante.

Qualcuno può proporre una soluzione migliore?

Grazie

risposta

0

È possibile memorizzare le statistiche in un #local variabili non. Come nella macro si fa <#assign treeStats = ...> e poi su chiamata loco:

<#import my="myutils.ftl"> 
... 
<@my.tree input /> 
<#assign stats = my.treeStats /> <#-- or whatever you want with my.treeStats --> 

sì, è imbarazzante, ma non ha FreeMarker out-params per restituire un risultato secondario. In realtà, si potrebbe fare un hack con loop-variabili, ma è forse troppo confuso, più se si ha realmente bisogno di un corpo, non è possibile utilizzare questo trucco:

<@my.tree input; res><#assign stats = res></@> 
1

Oppure si può anche utilizzare una variabile globale come deposito per le tue statistiche:

<#global stats = [] /> 

<#-- then when you call your function --> 
<#assign = method() /> 

<#function method param = ""> 
    <#-- do something and before you return you push the stats to the global variable, if you choose my approach of "merging" sequences, be careful that you wrap the new stats item also in a sequence or it will fail miserably =) --> 
    <#global stats = stats + [{"statvar1": 10, "statvar2": 30}] /> 

    <#return whateveryoulike /> 
</#function>