#include and #parse in email templates

For general questions and discussions specific to the AbleCommerce 7.0 Asp.Net product.
Post Reply
hamidkm
Ensign (ENS)
Ensign (ENS)
Posts: 3
Joined: Thu Feb 11, 2010 2:25 am

#include and #parse in email templates

Post by hamidkm » Thu Feb 11, 2010 12:02 pm

I am trying to use the nVelocity #include directive to include a html fragment inside the the email templates, like this:

#include("env.vm")
or
#parse("env.vm")

But, no matter where I put the env.vm file I get this error: Some error has occurred while parsing email template. Please fix the email template 'Customer Order Notification' before trying to send email. Error details:
Unable to find resource 'env.nm'

Does anyone have any idea where I should put these kind of file so nVelocity engine can find it?

Looks like the default TEMPLATE_ROOT is c:\windows\System32. Is there a way to change it?

garrisonh
Ensign (ENS)
Ensign (ENS)
Posts: 1
Joined: Tue Dec 04, 2012 10:52 am

Re: #include and #parse in email templates

Post by garrisonh » Tue Dec 04, 2012 2:25 pm

For anybody who has this same problem, I was able to get around it by putting the following code in the Init function of a custom http module.

Code: Select all

//create new NVelocityEngine object - without calling a constructor
CommerceBuilder.Messaging.NVelocityEngine newEngine = (CommerceBuilder.Messaging.NVelocityEngine)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(CommerceBuilder.Messaging.NVelocityEngine));
//invoke constructor of parent
typeof(NVelocity.App.VelocityEngine).GetConstructor(new Type[] { }).Invoke(newEngine, null);
//set property and initialize
newEngine.SetProperty("file.resource.loader.path", "C:\\inetpub\\wwwroot\\App_Data\\EmailTemplates\\1\\");
newEngine.Init();
//save newEngine in static private field in NVelocityEngine class
typeof(CommerceBuilder.Messaging.NVelocityEngine).GetField("a", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).SetValue(null, newEngine);
The problem is caused by the CommerceBuilder.Messaging.NVelocityEngine constructor. All it does is create the parent (NVelocity.App.VelocityEngine) and immediately call Init(). Unfortunately, it seems that any properties have to be set before the init function is called. Any properties that aren't explicitly set will just use default values. The default value for the file.resource.loader.path property is "." (the current directory) which is typically "c:\windows\System32".

The code above creates a CommerceBuilder.Messaging.NVelocityEngine object without calling its constructor. Then it calls the constructor for the parent object, sets the file.resource.loader.path property, and initializes the NVelocity engine. Then it replaces the static NVelocityEngine object saved in the CommerceBuilder.Messaging.NVelocityEngine class.

This seems to work correctly for AbleCommerce 7.0.7 but may break in future versions.

Post Reply