Archive

Archive for December, 2013

Exploring the CodeFluent Runtime: The Template Engine

December 26, 2013 Leave a comment

As you probably know, we released a few year ago the CodeFluent Runtime as a free Nuget Package named CodeFluentRuntimeClient. This is a set of utilities which is usable across all types of .NET applications (WPF, WinForms, ASP.NET, console, Windows service, etc.) and aims to ease the developer’s life.

Today, I’d like to introduce you, as part of the Exploring the CodeFluent Runtime series, an easy-to-use class to generate documents from a template source file.
You should ask yourself what is a template in term of software development. It’s simply a mixture of text blocks and control logic that can generate an output file. With our template engine, the control logic is written in JavaScript as fragments of program code. By default, the engine is based on the fast IE9+ “chakra” JavaScript engine developed by Microsoft for its Internet Explorer web browser.

Before we go any further it’s important to briefly describe the two following classes from the CodeFluent.Runtime.TemplateEngine namespace:

Template: Defines properties and characteristics of an ActiveX Scripting template and provides a set of methods to load and process a template file.

ParsedTemplate: In-memory and compiled representation of your template file (JavaScript).

The following diagram shows how the template engine internally works:

CodeFluentRuntimeClient Template

If you want to understand how to parse and execute JavaScript by C#, just have a look to this StackOverflow discussion. You’ll find how to interop with the JavaScript “IE9+ Chakra” JavaScript engine.

The easiest way to understand how to use the template engine is by way of an example. The first thing we have to do is create our template file.

Consider the following Rtf input file:

RTF Input file

Rtf Input file

You can download the template file here.

The “<% %>” tag represents the JavaScript code blocks. Let’s use the Template engine in order to process the template described above:

// The ComVisible indicates that the managed type is visible to COM.
[ComVisible(true)]
public class OrderLine
{
    public string ProductName { get; set; }
    public decimal UnitPrice { get; set; }
    public int Quantity { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        // initialize the argument dictionary.
        IDictionary<string, object> arguments = new Dictionary<string, object>();
        arguments.Add("orderLine1", new OrderLine() { ProductName = "Product A", Quantity = 5, UnitPrice = 12 });
        arguments.Add("orderLine2", new OrderLine() { ProductName = "Product B", Quantity = 10, UnitPrice = 30 });
        arguments.Add("orderLine3", new OrderLine() { ProductName = "Product C", Quantity = 4, UnitPrice = 40 });

        CodeFluent.Runtime.TemplateEngine.Template template = new CodeFluent.Runtime.TemplateEngine.Template();

        // Load the source template with the argument initialized above.
        template.Load("PurchaseOrder_Template.rtf", arguments.Keys.ToArray());

        using (StreamWriter writer = new StreamWriter(@"PurchaseOrder.rtf"))
        {
            // Run the template using the CodeFluent Runtime Template engine.
            template.Run(writer, arguments);
        }
    }
}

For running this code you have just to reference the CodeFluent Runtime Client Library and when executing it you’ll get the generated output file :

Rtf Output file

Rtf Output file

It’s good to know that the template engine is fully extendable. It would be helpful if you want to add your own keywords or business rules. For this purpose, you should inherit from the Template and/or ParsedTemplate objects.

On the same topic and through the CodeFluent Entities product, we are shipping a Template producer which is an engine that allow developers to generate text files from template containing C# code blocks.

Happy templating,

Antoine Diekmann