Well, to begin, this is not a new project – I have developed most of it during the end of 2015 with occasional fixes and new features along the way (recently added support for DLR and dynamic objects). But, in the great tradition of the “blogger” I feel obligated to share my baby with the world.
The project was born from a specific need we had at the company I was employed at the time: simplify email templates. You see, the templates were being kept by the developers as they were written using a tortured Razor engine (yes, the same used by ASP.NET). The amount of change requests coming in was, well, high. It became clear, we needed a simple way to allow non-technical staff to maintain the templates themselves — I know, sounds obvious, right!?
I have considered different existing libraries to achieve this, including the beloved by all “String.Replace()” method, but all options were either too simple to be useful or too complex to be used by non-techies. Nothing fit exactly into what we wanted. This prompted me to write the XtraLiteTemplates library.
The core principles of the library are: must allow complex templates and must be usable by non-technical staff. Both are achieved by what I call “domain-specific templates“. The library allows a developer to define her own simple template language using existing constructs. Simply put you can define things like “WHILE (expr) DO … END” and “DO (expr) IF (expr)“. Or even something like “PRICE OF (expr)“. One can define any constructs that fit the business needs.
By default, the library comes with two “dialects” (the domain-specific languages): Standard and Code Monkey. Code Monkey dialect if a super-set of the Standard and simplified constructs, aimed at developers). The following example shows a small use of the library:
private static async Task MainAsync(string[] args) { var @object = new { Name = "Alex", Friends = new[] { "Mary", "John", "Peter" } }; const string template = @" {PRE}{person.Name} has {person.Friends.Length} friends: {FOR friend IN person.Friends}{friend}{WITH}, {END}. He is{IF person.Friends.Length == 0} not{END} a happy guy!{END}"; var test = await XLTemplate.EvaluateAsync( CodeMonkeyDialect.Default, template, CancellationToken.None, person => @object).ConfigureAwait(false); Console.WriteLine(test); }
Note that by default the engine removes additional white-spaces. To prevent that I used the “PRE” directive.
There is enough documentation in the project’s wiki so I am not going to repeat it here. Hope this project helps someone in need of a simple but powerful template library (no, String.Replace is not an option!).