This templating library is an abstraction above various templating engines and our storage library. It handles loading from any location supported by our storage library. It will also transparently cache templates for you.
It has support for partials, files prefixed with an underscore _
will be considered as partials
and loaded as such.
In your project.json add required dependencies :
"GeekLearning.Storage.FileSystem": "0.5.0",
"GeekLearning.Templating": "0.5.0",
"GeekLearning.Templating.Handlebars": "0.5.0",
Then add required settings in your appsettings.json
file. In this example, we will
use FileSystem provider to configure a storage provider which will load files from
a Templates
folder relative to Application Root. This could be configured to use
an Azure Container instead (see storage documentation).
"Storage": {
"Stores": {
"Templates": {
"Provider": "FileSystem",
"Parameters": {
"Path": "Templates"
}
}
}
}
We will then create an EmailTemplates
class. It will be based on TemplateCollectionBase
which eliminates most of the boilerplate code required to load and execute a template.
public class EmailTemplates : TemplateCollectionBase
{
public EmailTemplates(IStorageFactory storageFactory, ITemplateLoaderFactory templateLoaderFactory) : base("Templates", storageFactory, templateLoaderFactory)
{
}
public Task<string> ApplyInvitationTemplate(InvitationContext context)
{
return this.LoadAndApplyTemplate("invitation", context);
}
public Task<string> ApplyInvitation2Template(InvitationContext context)
{
return this.LoadAndApplyTemplate("invitation2", context);
}
public Task<string> ApplyInvitation3Template(InvitationContext context)
{
return this.LoadAndApplyTemplate("SubDir/invitation", context);
}
}
Then in your Startup.cs
file add required dependencies and configuration to the DI container.
services.AddMemoryCache();
services.AddStorage().AddFileSystemStorage(HostingEnvironment.ContentRootPath).AddAzureStorage();
services.AddTemplating().AddMustache().AddHandlebars();
services.AddScoped<EmailTemplates>();
services.Configure<StorageOptions>(Configuration.GetSection("Storage"));
Our abstraction is composed of a few interface and a base class to reduce boilerplate code when working with templates.
First interface is ITemplateLoaderFactory
.
public interface ITemplateLoaderFactory
{
ITemplateLoader Create(IStore store);
}
You can use this interface to get an ITemplateLoader
for a specific IStore
(see storage documentation)
public interface ITemplateLoader
{
Task<ITemplate> GetTemplate(string name);
}
Once you have an ITemplateLoader
interface you can retrieve a specific template by is name.
If it's not already loaded, it will be read from the IStore
.
public interface ITemplate
{
string Apply(object context);
}
A ITemplate
reference can be executed on a specific context
using Apply
method.
Handlebars
provider allows you to load .hbs
templates
(see Handlebars.js). It relies on Handlebars.Net port.
This is our recommanded option as it compiles templates for better performance.
Mustache.js
provider is a mustache provider allowing you to load .mustache
templates. It is based on
mustache sharp work. As we've go no answer
from author, we are maintaining dotnet core support on our own fork.
A good thing is it has no dependency on Emit or Expression so it might be usefull on some edge cases.
Note that it does not support partials.
- Design and add Helpers support for Handlebars Engine.
- Additional providers (haml through NHAML or NVelocity).