Blog Archives

Using Sitecore.NVelocity library to create email templates

If you find yourself sending emails from a Sitecore application and you don’t want to generate the emails in code-behind, an easy way to create basic email templates is by using the NVelocity library built into Sitecore API.

What is NVelocity?

NVelocity is a .Net port of the popular template engine Velocity written in Java. The .Net port is mostly recently maintained by the guys at Castle Project.

Sitecore’s NVelocity library

This is probably a bit older but still works fine for basic email templates.

One problem I repeatedly ran into, with both the Sitecore NVelocity library and the Castle Project NVelocity implementation was loading template files from the file system. After wasting a couple of hours on this (repeatedly the template file could not be found, no matter what I tried) I gave up and loaded the templates into memory using a TextReader and then applied the template using VelocityHelper.Evaluate.

Unfortunately there is nowhere near enough documentation online about NVelocity issues with reading template files, or the Sitecore NVelocity library to get much help with this problem. Basically any call to load a template file (using GetTemplate) would result in a ResourceNotFoundException.

Example of a NVelocity email template

Thank you for your registration

Your username was: $username

The delivery details you gave were:

Address: $address
City: $city
State: $state

Thank you

The file above should be saved somewhere as a .vm file, for example template1.vm. This is a basic email template for NVelocity, you use the dollar sign followed by a variable name to define somewhere that content is replaced, so in the example ‘username’, ‘address’, ‘city’ and ‘state’ are template data values.

Replacing content

This is the implementation that worked for me.

private void SendEmail()
{
 System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
 System.Text.StringBuilder sb = new System.Text.StringBuilder();
 string filePath = HttpContext.Current.Server.MapPath("/common/templates/template1.vm");
 string template;

 if (!System.IO.File.Exists(filePath))
 throw new ApplicationException("Could not find email template file: " + filePath);

 System.IO.TextReader reader = new System.IO.StreamReader(filePath);
 template = reader.ReadToEnd();

 NVelocity.VelocityContext context = new NVelocity.VelocityContext();

 context.Put("username", "hansolo");
 context.Put("address", "1337 Isme Street");
 context.Put("city", "Built On Rock N' Roll");
 context.Put("state", "VIC");

 message.From = new MailAddress("web@testsender.com");
 message.To.Add("recipient@test.com");
 message.Subject = "Test of NVelocity as email templating engine";
 message.IsBodyHtml = false;

 NVelocity.App.Velocity.Init();
 message.Body = Sitecore.Text.NVelocity.VelocityHelper.Evaluate(context, template, "example-template-replace");

 MainUtil.SendMail(message);            
}

What this does is takes the contents of the template1.vm file and replace all the values found inside using the values defined in the context.Put statements. Note these values don’t need to include the dollar sign.

Calling VelocityHelper.Evaluate and passing in a NVelocity VelocityContext, in-memory template (read from file system using System.IO) and log name will return the contents of the template with specified values replaced from the context passed in.

Output Email body

From the example above this is the body of the email sent.

Thank you for your registration

Your username was: wonaldng

The delivery details you gave were:

Address: 1337 Isme Street
City: Built On Rock N' Roll
State: VIC

Thank you

Useful links

Castle Project: Using NVelocity – the most referenced tutorial for this library.

Velocity @ Apache.org – Java version reference documentation.

Velocity is, on it’s own, a very strong template engine. In an advanced situation it can do a lot more than just replacing variables in a template, including things like program-control and conditional statements.

Hope this saves you some time if you ever have to go down this path.

LinkedInDiggRedditTumblrGoogle GmailPrintFriendlyEmailShare

Switch to our mobile site