Примеры NVelocity ASP.NET

Я хочу использовать NVelocity в моем приложении ASP.NET MVC, а не в качестве механизма просмотра, просто для визуализации некоторых шаблонов электронной почты.

Однако я не могу заставить его работать. Я загрузил его из проекта замка и последовал примеру на http://www.castleproject.org/others/nvelocity/usingit.html#step1.

Независимо от того, что я пытаюсь, мне кажется, что я не могу загрузить шаблон, расположенный на моем сайте. В примере предлагается использовать абсолютный путь, который я безуспешно пытался:

Template t = engine.GetTemplate("/Templates/TestEmail.vm");

Так что, пожалуйста, кто-нибудь может привести мне два примера. Один из загрузки шаблона, расположенного в каталоге веб-сайта, а второй - анализ строковой переменной (поскольку вполне вероятно, что мои шаблоны будут храниться в базе данных).

Большое спасибо Бен


person Ben Foster    schedule 17.03.2010    source источник
comment
не уверен, что это поможет, но здесь есть неплохая статья: codeproject.com/KB/ aspnet / nvelocityaspnet.aspx   -  person rohancragg    schedule 17.03.2010
comment
@rohancragg - да, я видел эту статью. Однако он довольно старый, и методы, используемые для обработки шаблонов, похоже, изменились с тех пор, как проект был передан Castle. Спасибо, в любом случае   -  person Ben Foster    schedule 17.03.2010


Ответы (3)


Я использовал этот класс в одном из своих прошлых проектов:

public interface ITemplateRepository
{
    string RenderTemplate(string templateName, IDictionary<string, object> data);
    string RenderTemplate(string masterPage, string templateName, IDictionary<string, object> data);
}

public class NVelocityTemplateRepository : ITemplateRepository
{
    private readonly string _templatesPath;

    public NVelocityTemplateRepository(string templatesPath)
    {
        _templatesPath = templatesPath;
    }

    public string RenderTemplate(string templateName, IDictionary<string, object> data)
    {
        return RenderTemplate(null, templateName, data);
    }

    public string RenderTemplate(string masterPage, string templateName, IDictionary<string, object> data)
    {
        if (string.IsNullOrEmpty(templateName))
        {
            throw new ArgumentException("The \"templateName\" parameter must be specified", "templateName");
        }

        var name = !string.IsNullOrEmpty(masterPage)
            ? masterPage : templateName;

        var engine = new VelocityEngine();
        var props = new ExtendedProperties();
        props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, _templatesPath);
        engine.Init(props);
        var template = engine.GetTemplate(name);
        template.Encoding = Encoding.UTF8.BodyName;
        var context = new VelocityContext();

        var templateData = data ?? new Dictionary<string, object>();
        foreach (var key in templateData.Keys)
        {
            context.Put(key, templateData[key]);
        }

        if (!string.IsNullOrEmpty(masterPage))
        {
            context.Put("childContent", templateName);
        }

        using (var writer = new StringWriter())
        {
            engine.MergeTemplate(name, context, writer);
            return writer.GetStringBuilder().ToString();
        }
    }
}

Чтобы создать экземпляр класса NVelocityTemplateRepository, вам необходимо указать абсолютный путь к корневому каталогу вашего шаблона. Затем вы используете относительные пути для ссылки на свои vm файлы.

person Darin Dimitrov    schedule 17.03.2010
comment
@Darin, я пробовал ваш пример, но все равно получаю ту же ошибку при попытке загрузить файл шаблона. Возможно, я ошибаюсь. Речь идет о шаблоне ~ / Content / Templates / TestEmail.vm, а мой код приведен ниже: var templatesPath = VirtualPathUtility.ToAbsolute (~ / Content / templates); ITemplateService templateService = новый NVelocityTemplateService (templatesPath); var objs = new Dictionary ‹строка, объект› (); вернуть templateService.RenderTemplate (TestEmail.vm, objs); - person Ben Foster; 17.03.2010
comment
VirtualPathUtility не возвращает абсолютный путь. Вам нужно передать абсолютный путь, например c:\mytemplates. Попробуйте вместо этого: Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @"Content\templates"). - person Darin Dimitrov; 17.03.2010
comment
Я перешел на Server.MapPath, чтобы получить физический каталог на сервере. Теперь работает угощение. Спасибо. - person Ben Foster; 17.03.2010

Я также добавил следующий метод для обработки строки вместо файла шаблона (скажем, при извлечении содержимого шаблона из базы данных):

        public string RenderTemplateContent(string templateContent, IDictionary<string, object> data)
    {
        if (string.IsNullOrEmpty(templateContent))
            throw new ArgumentException("Template content cannot be null", "templateContent");

        var engine = new VelocityEngine();
        engine.Init();

        var context = GetContext(data);

        using (var writer = new StringWriter()) {
            engine.Evaluate(context, writer, "", templateContent);
            return writer.GetStringBuilder().ToString();
        }
    }

И использовал StructureMap для инициализации службы:

            ForRequestedType<ITemplateService>()
            .TheDefault.Is.ConstructedBy(()=> 
                new NVelocityTemplateService(HttpContext.Current.Server.MapPath("~/Content/Templates/")));
person Ben Foster    schedule 17.03.2010

Вы можете найти компонент TemplateEngine полезным.

Это абстракция над механизмами шаблонов с реализацией NVelocity, аналогичная ответу Дарина, но он должен работать немного лучше, поскольку он использует один экземпляр VelocityEngine (в отличие от инициализации одного экземпляра на рендеринг) и имеет дополнительное кеширование. Он также имеет несколько других функций, таких как ведение журнала, переопределение свойств NVelocity и загрузка шаблонов из ресурсов сборки.

person Mauricio Scheffer    schedule 20.03.2010