Desktop, tools, Web

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

Desktop

Handling DialogBox with WPF (MVVM)

imageHandling dialog windows in WPF using MVVM pattern is not such obvious thing as people may suspect. There are many discussions about it, and people come out with some solutions, that are more or less difficult, but still not perfect. I don’t like any and it made me describe my own.

 

 

 

Common solutions

As I have found, there is a couple of solutions for the problem. The most common ones are:

  • DialogService – creating a service used to handle all dialogs/windows in the application. Such a service can be used by any ViewModel. This way the view model knows that some other part of application must be shown/hidden as a dialog window. It’s somehow a design smell (link1, link2, etc.)
  • Dialog content injection – declare a markup of the dialog in XAML. Such a markup is then used to generate the new dialog window. Its visibility is controlled by a binding between ViewModel’s “Showing” property and the View. I thinks it’s better than the first one, but there’s too much logic behind the scene (link)
    Simplest approach

I think both solutions don’t answer my real need. I had a chat with an architect about this and we came to some simple conclusions:

  • MVVM is to create a good separation of presentation layer and the rest of the application, mainly by using bindings
  • Showing some UI parts as a dialog window or a panel, tab, accordion etc. is a presentation detail. It should be responsibility of the to control such a behaviour.
  • View doesn’t need to be stupid. WPF+MVVM developers got used to moving all the view code to bindings, but let’s not overuse it. If something is simpler to be done in code-behind, let it stay there.

In the end, I decided to invoke the famous “ShowDialog” method in the code-behind and pass the context (view model) to the newly created window. In the simplest case the view should not process the DialogResult, because this is the view model’s role. In my case the communication between the view model of the “Main window” and view model of the “dialog window” is based on events. Such a “Save” event exposed by the dialog’s view model can be used by “Main window” view model to add some item to a collection/repository but in the same time it can be used by the view of “dialog window” to close it.

 

Sample

The most beautiful words will never reflect the beauty of a sample, so here it is: Link