1

我有一组简单的速度模板。当我尝试使用 NVelocity 进行合并时,其他模板中的宏未执行。模板内容如下:

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

合并时,输出为:

Hello User1!

    #age(33)

Hello User2!

    #age(13)
4

1 回答 1

1

该宏不起作用,因为 NVelocity(及其祖先 Velocity)#age在解析时确定是指令还是宏,而#age宏在运行时在跳转到另一个模板时被发现,因此它作为文本传递。

要解决这个问题,您需要在解析器解析您V1.vm#foreach. 您显然可以通过将宏内联到该文件中来做到这一点,但我假设您打算在其他模板中重用它,这就是您现在将它分开的原因。

另一种选择是将宏放入宏库中,一个 NVelocity 将自动加载(VM_global_library.vm)或自定义一个。如果您VM_global_library.vm在模板目录的根目录下创建一个名为的模板,NVelocity 将在解析任何内容之前首先自动加载它,否则创建您自己的宏模板文件并将其注册VelocityEnginevelocimacro.library属性中。有关属性的更详细说明,请参阅Velocity 文档

我已经包含了一个使用自定义宏库的工作示例:

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());
        }
    }
}
于 2014-07-01T06:22:08.393 回答