2010-03-17 3 views
3

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

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

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

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

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

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

+0

не уверен, что это поможет, но theres довольно хорошая статья здесь: http://www.codeproject.com/KB/aspnet/nvelocityaspnet.aspx – rohancragg

+0

@rohancragg - да, я видел эту статью. Однако он довольно старый, и методы обработки шаблонов, похоже, изменились с тех пор, как проект был захвачен замком. Спасибо в любом случае –

ответ

6

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

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.

+0

@Darin, я попробовал ваш пример, но все равно получаю ту же ошибку при попытке загрузить файл шаблона. Возможно, я ошибаюсь в своих путях. Этот шаблон является ~/Content/Templates/TestEmail.vm, а мой код ниже: var templatesPath = VirtualPathUtility.ToAbsolute ("~/Content/templates"); ITemplateService templateService = новый NVelocityTemplateService (templatesPath); var objs = new Словарь (); return templateService.RenderTemplate ("TestEmail.vm", objs); –

+0

VirtualPathUtility не возвращает абсолютный путь. Вам необходимо пройти абсолютный путь, например 'c: \ mytemplates'. Попробуйте это вместо: 'Path.Combine (HostingEnvironment.ApplicationPhysicalPath, @" Content \ templates ")'. –

+0

Я перешел на Server.MapPath, чтобы получить физический каталог на сервере. Сейчас работает угощение. Благодарю. –

2

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

 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/"))); 
1

Возможно, вы найдете TemplateEngine component.

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

+0

Спасибо - это было полезно. –

Смежные вопросы