macros not rendering in NVelocity

青春壹個敷衍的年華 提交于 2020-01-06 05:01:09

问题


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)

回答1:


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 named VM_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 the VelocityEngine with the velocimacro.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:

class Customer
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int GetAge() { return Age; }
}
class Program
{
    static void Main(string[] args)
    {
        VelocityEngine velocityEngine = new VelocityEngine();
        ExtendedProperties extendedProperties = new ExtendedProperties();
        extendedProperties.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, "Templates");
        extendedProperties.SetProperty(RuntimeConstants.VM_LIBRARY, "MyMacros.vm");
        velocityEngine.Init(extendedProperties);

        VelocityContext context = new VelocityContext();
        context.Put("customers", new Customer[] {
            new Customer { Name = "Jack", Age = 33 },
            new Customer { Name = "Jill", Age = 13 }
        });

        using (StringWriter sw = new StringWriter())
        {
            bool result = velocityEngine.MergeTemplate("V1.vm", context, sw);
            Console.WriteLine(sw.ToString());
        }
    }
}


来源:https://stackoverflow.com/questions/24450670/macros-not-rendering-in-nvelocity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!