Hello Jonathan,

/"Well, in general, once you want to do anything moderately complex with velocimacros, the thing breaks because it's.... *junk.* :-)"/

It's not nice to say about a different library(a "competitor") "it's junk", even if the library is not as good as yours(I'm not sure if you a commiter or just a user of FreeMarker).

I agree, velocity has some weak parts, but this doesn't mean is "junk". I'm not pro Velocity and against FreeMarker of vice versa, and I am glad for the existence of projects like Velocity or FreeMarker(all the Apache projects, etc).

So let's play nice...You can post articles about "FreeMarker is better that Velocity" but do it with professionalism.

PS . My framework(yet another java framework??? :) ) allows me to choose between any template engine without modify any Java code so it is transparent for me in general. This situation with calling dynamically a macro is the first exception in years, usually I have anything I need in Velocity, I don't need to think about another library(not that the Velocity is the only good template engine, but I got used with it).


Jonathan Revusky wrote:
Adrian Tarau wrote:
I've always used #if to implement the 'switch' but I think, even for 3-4 conditions, the template will look cleaner.

Instead of

#if('renderLabel' == $macroToCall)
#renderLabel($component)
#elseif('renderInput' == $macroToCall)
#renderInput($component)
#elseif(...)
...
#end

we will have

#call($macroToCall $component).


This kind of thing is trivial in FreeMarker. For example, suppose you had:

<#assign macroHash = {'renderLabel' : labelMacro, 'renderInput' : renderMacro, .... >

and then, supposing you have an action string, like suppose:

[#assign action = 'renderLabel']

then you could invoke the macro via:

<@macroHash[action] component />


The thing is that macros in FreeMarker are variables, and can be in hashes or assigned to variables or whatever, and also the foo in <@foo/> to invoke the macro can be any arbitrary expression.

So, for example, suppose the macro you want to invoke is in the string macroName, you could invoke it via:

<@.vars[macroName] component/>

(.vars is a special built-in hash that contains the variables available in the template and since macros are variables as well, .vars[macroName] is the macro with the name macroName and it can be invoked this way, or you could create a variable.

<#assign myMacro = .vars[macroName]>

and invoke it via:

<@myMacro component/>
Right below this, Mr. Van Bergen mentions Anakia, which is an add-on to Velocity for processing XML. He neglects to mention that FreeMarker provides similar XML processing functionality (though the implementation is much more complete, since it supports XML namespaces, for example) as part of its core feature set. Declarative XML processing is supported in FreeMarker via the #visit and #recurse directives, which are core directives in the FreeMarker language. One would infer from what the article says that XML processing is a point in favor of Velocity, when, really, quite the opposite is the case. The XML processing functionality available for Velocity is add-ons like Anakia and DVSL that are basically abandonware, where the XML processing support in FreeMarker is a core part of the product, and is clearly supported.

Well, in general, once you want to do anything moderately complex with velocimacros, the thing breaks because it's.... junk. :-)

Here is a blog entry I wrote regarding some of this sort of thing:

http://freemarker.blogspot.com/2007/12/velocity-of-freemarker-looking-at-5.html

Jonathan Revusky
--
lead developer, FreeMarker project, http://freemarker.org/


In case of a value outside the 'domain' you will get an exception "Macro not found ....".

We could have even a directive which will simulate the switch default branch.

#callWithDefault($macroToCall $defaultMacro ....) - of course the name should be shorter.

Christopher Schultz wrote:
Adrian,

Adrian Tarau wrote:
I have the following problem : I would like to call a macro but the macro
name must be a variable.

This is more of a question for the user's list, not the dev list. In the future, please post there.

Ex: instead of #renderLabel($component) to have #call("renderLabel"
$component) - of course "renderLabel" can be any (existing) macro name.

How many possibilities can you have for $component? Are they unlimited, or constrained to maybe 5 possibilities? I'm wondering because you could easily do it like a switch:

#if('renderLabel' == $macroToCall)
#renderLabel($component)
#elseif('renderInput' == $macroToCall)
#renderInput($component)
#elseif(...)
...
#end

-chris



Reply via email to