Skip to content

The Makeshift Template Engine

Travis Parks edited this page Oct 24, 2013 · 1 revision

I am working on a small project that sends out emails out on a nightly basis. Since it is a stand-alone application, it didn't make sense to include a bunch of 3rd-party dependencies. So, I wrote a simple template engine. Here it is:

private static string generate(string template, object data)
{
    string pattern = @"{{(?<key>[^,:]+?)(,(?<align>-?\d+))?(:(?<format>.+?))?}}";
    Regex regex = new Regex(pattern, RegexOptions.ExplicitCapture);
    return regex.Replace(template, match => getReplacement(match, data));
}

private static string getReplacement(Match match, object data)
{
    string alignment = match.Groups["align"].Value;
    string formatting = match.Groups["format"].Value;
    string format = getFormat(alignment, formatting);

    string key = match.Groups["key"].Value;
    PropertyInfo property = data.GetType().GetProperty(key);
    object value = property == null ? null : property.GetValue(data);

    string replacement = String.Format(format, value);
    return replacement;
}

private static string getFormat(string alignment, string formatting)
{
    StringBuilder format = new StringBuilder("{0");
    if (!String.IsNullOrWhiteSpace(alignment))
    {
        format.Append(',');
        format.Append(alignment);
    }
    if (!String.IsNullOrWhiteSpace(formatting))
    {
        format.Append(':');
        format.Append(formatting);
    }
    format.Append("}");
    return format.ToString();
}

This is a pretty handy piece of code if your templates are logic-less. Personally, I am reading my template in from an HTML file I am including with the application. This way, I can customize the email without having to redeploy the entire code base.

If you are wondering why Mustache# is so large when the core code is so small, consider this: this code would be horribly slow if run against many data objects; this code doesn't allow the creation of arbitrary tags; it can't work against dictionaries; it doesn't handle whitespace very well. All-in-all, Mustache# is pretty lean when you consider all of its functionality. It's basically a small language parser.

Clone this wiki locally