user1584078
user1584078

Reputation: 161

freemarker functions vs macros

Hello freemarkers gurus

I understand that the difference between freemarker functions and macros is that macros can print to the output, but cannot return values, while functions can return values but cannot print to the output.

Well, I am having a problem because I need both to print and return values:

I am doing recursive tree exploration with freemarker and therefore I have a macro being called recurvively. As the tree is being explored , I need both to print node information to the output, but also compute and return statistics about the nodes explored ( for example the sum of a specific property of the nodes explored)

If I use macro being called recurvively I can print node information but cannot return the statistics to the calling entity.

If I use a function recursively called, I can return the statistics but cannot print node information on the output.

One solution could be to explore the tree twice, once to print node informations and another to collect statistics, but I would hate to use this unelegant solution.

Can someone propose a better solution?

Thanks

Upvotes: 16

Views: 12272

Answers (2)

exside
exside

Reputation: 3894

Or you can even use a global variable as storage for your stats:

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

Upvotes: 3

ddekany
ddekany

Reputation: 31152

You can store the statistics in a non-#local variable. Like in the macro you do <#assign treeStats = ...> and then on call-site:

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

Yeah, it's awkward, but FreeMarker has no out-params to return a secondary result. Actually, you could do a hack with loop-variables, but it's maybe too confusing, plus if you really need a body, you can't use this trick:

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

Upvotes: 1

Related Questions