2012-08-08 16 views
9

Witam freemarkers gurufunkcje freemarker vs makra

Rozumiem, że różnica między funkcjami freemarker i makr jest to, że makra mogą drukować do wyjścia, ale nie może zwracać wartości, podczas gdy funkcje mogą zwracać wartości, ale nie można drukować na wyjściu.

Cóż, mam problem, bo muszę się zarówno do wydrukowania i zwracane wartości:

robie rekurencyjną eksploracji drzewo z freemarker i dlatego mam makro miano recurvively. Podczas eksploracji drzewa potrzebuję zarówno wydrukować informacje o węźle na wyjściu, ale także obliczać i zwracać statystyki dotyczące eksplorowanych węzłów (na przykład suma określonej właściwości eksplorowanych węzłów)

Jeśli używam makro nazywany jest recurvively mogę drukować informacje węzła, ale nie może powrócić do statystyk podmiotu wywołującego.

Gdybym użyć funkcji rekursywnie nazwie, mogę powrócić statystyki, ale nie można drukować informacje węzła na wyjściu.

Jednym z rozwiązań mogłoby być zbadanie drzewa dwa razy, raz, aby wydrukować informacje węzłów i innym do gromadzenia danych statystycznych, ale nie chciałbym używać tego unelegant rozwiązanie.

Czy ktoś może zaproponować lepsze rozwiązanie?

Dzięki

Odpowiedz

0

można zapisać statystyki w niebędącego #local zmiennej. Podobnie jak w makro zrobić <#assign treeStats = ...> a następnie na wezwanie miejscu:

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

Tak, to jest niewygodne, ale FreeMarker ma out-params zwraca wynik wtórnego. Faktycznie, można zrobić hack z pętlą-zmiennych, ale to może być zbyt skomplikowane, plus jeśli naprawdę potrzebujemy ciała, nie można korzystać z tej sztuczki:

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

lub można nawet użyć zmiennej globalnej jako do przechowywania swoich statystykach:

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