I have simple set of velocity templates. When I am trying to merge using NVelocity, the macros from other templates are not executing. The template contents are as follows:
V1.vm
#parse("V2.vm")
#foreach( $customer in $customers)
Hello $customer.Name!
#set($a =$customer.getage())
#age($a)
#end
V2.vm
#macro ( age $a )
#if($a<18)
Minor
#else
Major
#end
#end
On merge, the output is:
Hello User1!
#age(33)
Hello User2!
#age(13)
The macro doesn't work because NVelocity (and its ancestor Velocity) determine if
#age
is a directive or macro at parse time, while the#age
macro gets discovered at runtime as it jumps into the other template, and so it is passed through as text.To get around this you need to make the macro available to the parser before it parses your
V1.vm
's#foreach
. You can obviously do this by putting the macro inline in that file, but I assume you intend to reuse it in other templates which is why you've got it separate now.The other option is to put the macro in the macro library, either the one NVelocity will automatically load (
VM_global_library.vm
) or a custom one. If you create a template namedVM_global_library.vm
at the root of your templates directory NVelocity will automatically load this first before parsing anything, otherwise create your own macro template file and register it with theVelocityEngine
with thevelocimacro.library
property. See the Velocity documentation for a more detailed explanation of the properties.I've included a working example of using a custom macro library: