Using NVelocity

I’ve recently started using NVelocity. Its a brilliantly simple and powerful templating engine that’s been ported from the Java world.

I was going to explain how it works, and how to use it in your app, but its easier just to show you a test and an implementation.

[TestFixture]

public class MyVelocityTransformerTest

{

[Test]

public void ShouldUseVelocityToMergeContextContentsWithTemplate()

{

Hashtable contextContents = new Hashtable();

contextContents["foo"] = "bar";

MyVelocityTransformer transformer = new MyVelocityTransformer();

Assert.AreEqual("foo is bar", transformer.Transform("testTransform.vm", contextContents));

}

}

public class MyVelocityTransformer

{

public string Transform(string transformerFileName, Hashtable transformable)

{

VelocityEngine engine = new VelocityEngine();

engine.SetProperty(RuntimeConstants_Fields.RUNTIME_LOG_LOGSYSTEM_CLASS, "NVelocity.Runtime.Log.NullLogSystem");

engine.SetProperty(RuntimeConstants_Fields.FILE_RESOURCE_LOADER_PATH, "templates");

engine.SetProperty(RuntimeConstants_Fields.RESOURCE_MANAGER_CLASS, "NVelocity.Runtime.Resource.ResourceManagerImpl");

engine.Init();

string output = "";

using(TextWriter writer = new StringWriter())

{

engine.MergeTemplate(transformerFileName, new VelocityContext(transformable), writer);

output = writer.ToString();

}

return output;

}

}

This assumes that a file called ‘templates\testTransform’ exists with the following contents:

foo is $foo

The benefit to NVelocity is it makes generating string content much cleaner than any other method I’ve seen. Times when you would want to use it include code generation, HTML generation, etc.

The velocity template language is rich enough to make it more powerful that using (say) string.Format() – the #if and #foreach directives are especially useful.

As with all tools and libraries, NVelocity should be used where appropriate. I’ve seen Java projects with hideously complex, un-unittested templates which are incredibally fragile and hard to debug. My advice is to keep your templates relatively small, and only use directives to just go below the surface of the objects in your context. If necessary, introduce presentation objects and create them in normal, unit testable, code.

Advertisements