Search code examples
c#.nettemplate-engineliquiddotliquid

DotLiquid, some beginner questions/observations


I'm investigating using dotliquid to replace a home grown piece of templating code and I'm wondering about the best way to achieve my goal.

The old code used to use sigils in the template and, together with a Dictionary, used regexes to search and replace. So you did something like this in the template file:

Specific error: {#ErrorId#}
Error description: {#Description#}
Additional information:{#AdditionalInformation#}

And in the C# code:

Dictionary<string, string> tokensAndValues = new Dictionary<string, string>
{
    {@"ErrorId", errorId},
    {@"Description", description},
    {@"AdditionalInformation", additionalInformation}
};

I came across dotnetliquid and it appears quite powerful (possibly overkill for my needs?). I've got it working but I want to ask if I'm going about this in the correct fashion?

It appears I'm forced to declare a class viz.

public class EmailTemplateInfo : Drop
{
    public string ErrorId { get; set; }
    public string Description { get; set; }
    public string AdditionalInformation { get; set; }
}

And then use that as follows:

Template.NamingConvention = new CSharpNamingConvention();
Template template = Template.Parse(templateText);

EmailTemplateInfo emailTemplateInfo = new EmailTemplateInfo
{
    AdditionalInformation = additionalInformation,
    Description = description,                    
    ErrorId = errorId
};

string htmlText = template.Render(Hash.FromAnonymousObject(new {emailTemplateInfo = emailTemplateInfo }));

A few questions:

  1. Is this the correct way to do this? If it is then I'll propose doing an addition to the docs that demonstrates this functionality.

  2. Secondly in the template that I use do I need to qualify the placeholders with the name of the variable like this?

    Specific error: {{emailTemplateInfo.ErrorId}}
    Error description: {{emailTemplateInfo.Description}}
    Additional information:{{emailTemplateInfo.AdditionalInformation}}
    
  3. I can't see how the naming convention declaration [Template.NamingConvention = new CSharpNamingConvention();] ties in with the template variable declaration below it. Is there some sort of global caching going on?


Solution

    1. Yes, inheriting from Drop is one way to do it. The other mechanism that DotLiquid provides is Template.RegisterSimpleType(...) - see the unit tests for examples.

    2. Yes, you do need to qualify property names with the name of the variable, as in your example. The alternative would be to create a Hash containing top-level keys for AdditionalInformation, Description, ErrorId, and pass that to template.Render(...). You can do that using Hash.FromDictionary(...), as shown here.

    3. The naming convention doesn't have a connection to the variable declaration. The naming convention is only used when resolving property names. For example, if you used RubyNamingConvention, then you'd need to write {{ emailTemplateInfo.additional_information }} in your template.