Example : #center( #bold("hello") )
No. A directive isn't a valid argument to a directive, and for most practical purposes, a Velocimacro is a directive.
However, there are things you can do. One easy solution is to take advantage of the fact that 'doublequote' (") renders its contents. So you could do something like
#set($stuff = "#bold('hello')" ) #center( $stuff )
You can save a step...
#center( "#bold( 'hello' )" )
Please note that in the latter example the arg is evaluated
inside
the Velocimacro, not at the calling
level. In other words, the argument to the Velocimacro is passed
in in its entirety and evaluated within the Velocimacro it was
passed into. This allows you to do things like :
#macro( inner $foo ) inner : $foo #end #macro( outer $foo ) #set($bar = "outerlala") outer : $foo #end #set($bar = 'calltimelala') #outer( "#inner($bar)" )
Where the output is
Outer : inner : outerlala
because the evaluation of the "#inner($bar)" happens inside #outer(), so the $bar value set inside #outer() is the one that's used.
This is an intentional and jealously guarded feature - args are passed 'by name' into Velocimacros, so you can hand Velocimacros things like stateful references such as
#macro( foo $color ) <tr bgcolor=$color><td>Hi</td></tr> <tr bgcolor=$color><td>There</td></tr> #end #foo($bar.rowColor() )
And have rowColor() called repeatedly, rather than just once. To avoid that, invoke the method outside of the Velocimacro, and pass the value into the Velocimacro.
#set($color = $bar.rowColor()) #foo( $color )
Currently, Velocimacros must be defined before they are first used in a template. This means that your #macro() declarations should come before using the Velocimacros.
This is important to remember if you try to #parse() a
template containing inline #macro() directives. Because the
#parse() happens at runtime, and the parser decides if a
Velocimacro-looking element in the template is a Velocimacro at
parsetime, #parse()-ing a set of Velocimacro declarations won't
work as expected. To get around this, simply use the
velocimacro.library
facility to have Velocity
load your Velocimacros at startup.
There is a property, meant to be used in
development
, not production:
velocimacro.library.autoreload
which defaults to false. When set to true along
with
<type>.resource.loader.cache =
false
(where <type> is the name of the resource loader that you are using, such as 'file') then the Velocity engine will automatically reload changes to your Velocimacro library files when you make them, so you do not have to dump the servlet engine (or application) or do other tricks to have your Velocimacros reloaded.
Here is what a simple set of configuration properties would look like.
file.resource.loader.path = templates file.resource.loader.cache = false velocimacro.library.autoreload = true
Don't keep this on in production.