Programming (back-end)

Generating HTML document from template using NVelocity

Web HTMLSometimes there is a need to generate a document (HTML report, e-mail etc.) from a given template. It’s simple when it comes to just replace some tokens, but in case of more complicated operations (dealing with collections, conditions, loops) it’s better to use advanced template engine. Most of us are familiar with many (even unconsciously): WebFormsViewEngine (ASP.NET WebForms), Spark (ASP.NET MVC), Razor (ASP.NET MVC) and probably many more (here’s a nice comparison). Unfortunately these famous ones depend on ASP.NET and it’s rather a big deal to use them in a simple library. Fortunately there is NVelocity that can be used as a standalone tool and gives pretty much flexibility.

NVelocity

NVelocity is a port of very famous template engine from Java world called Apache Velocity that makes it possible to build MVC application (used for example by JIRA or Spring Framework). The latest version of NVelocity is a part of Castle Project and can be downloaded from github (other versions stored on codeplex or sourceforge are no longer supported). You can also use Nuget to do the same.

Velocity alone is documented pretty well, but also the library in Castle Project repository contains a lot of samples (I believe each single keyword has a separate document with sample usage).

NVelocity does not need any extra references but NVelocity.dll that you can build on your own or take it from the sample app in the end of this post.

Sample usage

Here’s is a code showing the sample usage of NVelocity:

Velocity.Init();

var model = new
{
	Header = "Test Header",
	Items = new[]
	{
		new { ID = 1, Name = "Name1", Bold = false},
		new { ID = 2, Name = "Name2", Bold = false},
		new { ID = 3, Name = "Name3", Bold = true}
	}
};
var velocityContext = new VelocityContext();
velocityContext.Put("model", model);

string template = string.Join(Environment.NewLine, new [] {
	"<p>",
	"   This is model.Header: <strong>$model.Header</strong>",
	"</p>",
	"<ul>",
	"#foreach($item in $model.Items)",
	"   <li>",
	"      item.ID: $item.ID,",
	   "#if ($item.Bold)",
	"      item.Name: <b>$item.Name</b>",
	   "#else",
	"      item.Name: $item.Name",
	   "#end",
	"   </li>",
	"#end",
	"</ul>"});

var sb = new StringBuilder();
Velocity.Evaluate(
	velocityContext,
	new StringWriter(sb),
	"test template",
	new StringReader(template));

This should produce the following result:

image

Some explanation

The snippet above is rather self-explanatory, but I’ll just point out the most important clauses. First thing is “Velocity.Init()” that initializes the engine and creates a pool of parsers (NVelocity uses singleton pattern). Next we need to create VelocityContext that is a map of velocity variables and .NET objects. Here I used anonymous objects, but you’re free to pass any .NET object. NVelocity interpret IEnumerable as NVelocity collection, it also supports .NET properties. “Velocity.Evaluate()” applies the context to the given template and produces result using passed TextWriter.

Demo

Feel free to experiment with the solution above: download

One thought on “Generating HTML document from template using NVelocity

Leave a comment