макросы не отображаются в NVelocity

У меня есть простой набор шаблонов скорости. Когда я пытаюсь выполнить слияние с помощью 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)

person Krishna Sarma    schedule 27.06.2014    source источник


Ответы (1)


Макрос не работает, потому что NVelocity (и его предок Velocity) определяют, является ли #age директивой или макросом во время синтаксического анализа, в то время как макрос #age обнаруживается во время выполнения, когда он переходит в другой шаблон, и поэтому он передается как текст .

Чтобы обойти это, вам нужно сделать макрос доступным для синтаксического анализатора до того, как он проанализирует ваши V1.vm #foreach. Очевидно, вы можете сделать это, поместив макрос в этот файл, но я предполагаю, что вы намерены повторно использовать его в других шаблонах, поэтому теперь он у вас отдельный.

Другой вариант - поместить макрос в библиотеку макросов: либо тот, который NVelocity загрузит автоматически (VM_global_library.vm), либо пользовательский. Если вы создаете шаблон с именем VM_global_library.vm в корне каталога шаблонов, NVelocity автоматически загрузит его перед тем, как что-либо анализировать, в противном случае создайте свой собственный файл шаблона макроса и зарегистрируйте его в VelocityEngine со свойством velocimacro.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());
        }
    }
}
person Jonathon Rossi    schedule 01.07.2014