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