-
Notifications
You must be signed in to change notification settings - Fork 78
The Makeshift Template Engine
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.