NVelocity does not find a template

I'm having difficulty using NVelocity in an ASP.NET MVC application. I use it as a way to create letters.

As far as I can understand the details that I pass, everything is correct, but the template cannot be loaded.

Here is the code:

private const string defaultTemplatePath = "Views\\EmailTemplates\\"; 

...

 velocityEngine = new VelocityEngine(); basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, defaultTemplatePath); ExtendedProperties properties = new ExtendedProperties(); properties.Add(RuntimeConstants.RESOURCE_LOADER, "file"); properties.Add(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, basePath); velocityEngine.Init(properties); 

BasePath is the correct directory, I inserted this value into the explorer to make sure it is correct.

 if (!velocityEngine.TemplateExists(name)) throw new InvalidOperationException(string.Format("Could not find a template named '{0}'", name)); Template result = velocityEngine.GetTemplate(name); 

'name' above is a valid file name in a folder defined as basePath above. However, TemplateExists returns false. If I comment on this convention and let it fail when the GetTemplate method is called, then the stack trace will look like this:

  at NVelocity.Runtime.Resource.ResourceManagerImpl.LoadResource(String resourceName, ResourceType resourceType, String encoding) at NVelocity.Runtime.Resource.ResourceManagerImpl.GetResource(String resourceName, ResourceType resourceType, String encoding) at NVelocity.Runtime.RuntimeInstance.GetTemplate(String name, String encoding) at NVelocity.Runtime.RuntimeInstance.GetTemplate(String name) at NVelocity.App.VelocityEngine.GetTemplate(String name) ... 

I'm at a dead end right now. I feel the answer is blindingly obvious, but I just can't see it at the moment.

+4
source share
5 answers

Good. So, I managed to do something, but it’s a bit of a hack and is not next to the solution I want, but something works.

Basically, I manually load the template into a string, and then pass that string to the velocityEngine.Evaluate () method, which writes the result to this StringWriter. A side effect of this is that the #parse instructions in the template do not work because they still cannot find the files.

 using (StringWriter writer = new StringWriter()) { velocityEngine.Evaluate(context, writer, templateName, template); return writer.ToString(); } 

In the above code, templateName does not matter since it is not used. template is a string containing the entire template preloaded from disk.

I will still appreciate any better solutions, as I really don't like this.

+1
source

Do you find using Castle NVelocityTemplateEngine ?

Download from the section "TemplateEngine Component 1.1 - September 29, 2009" and refer to the following assemblies:

 using Castle.Components.Common.TemplateEngine.NVelocityTemplateEngine; using Castle.Components.Common.TemplateEngine; 

Then you can simply call:

 using (var writer = new StringWriter()) { _templateEngine.Process(data, string.Empty, writer, _templateContents); return writer.ToString(); } 

Where:

  • _templateEngine - your NVelocityTemplateEngine
  • data strong> - your information dictionary (I use a dictionary to allow me to access objects using the key ($ objectKeyName) in my template.
  • _templateContents is the template string itself.

I hope this helps you!

Just to add, you'll want to put this in a static method that returns a string, of course!

+5
source

If this problem was recent - NVelocity must be initialized with the location of the template files. In this case, mergeValues is an anonymous type, so in my template I can just refer to $Values.SomeItem :

  private string Merge(Object mergeValues) { var velocity = new VelocityEngine(); var props = new ExtendedProperties(); props.AddProperty("file.resource.loader.path", @"D:\Path\To\Templates"); velocity.Init(props); var template = velocity.GetTemplate("MailTemplate.vm"); var context = new VelocityContext(); context.Put("Values", mergeValues); using (var writer = new StringWriter()) { template.Merge(context, writer); return writer.ToString(); } } 
+3
source

Tests are the highest authority:

http://fisheye2.atlassian.com/browse/castleproject/NVelocity/trunk/src/NVelocity.Tests/Test/ParserTest.cs?r=6005#l122

Or you can use the TemplateEngine component , which is a thin shell around NVelocity, which simplifies the work.

0
source

All Articles