Templating
Overview
Smartstore renders dynamic content with the DotLiquid engine. Liquid syntax powers email bodies and other text snippets and can be extended with custom filters or tags. Templates are executed against arbitrary models and support localization out of the box.
Template files
Liquid templates use the .liquid
extension. When a path starts with ~/
it is resolved against the application root; otherwise the current template is searched under Views/Shared/EmailTemplates
.
Themes/<ThemeName>/Views/Shared/EmailTemplates/order.liquid
Rendering templates
Inject ITemplateEngine
into a service and render a template string or file with a model:
public class OrderEmailBuilder
{
private readonly ITemplateEngine _templates;
public OrderEmailBuilder(ITemplateEngine templates) => _templates = templates;
public async Task<string> BuildAsync(Order order)
{
var source = "Hello {{ Customer.FirstName }}, your order {{ Order.CustomOrderNumber }} totals {{ Order.OrderTotal }}.";
var model = new { Order = order, Customer = order.Customer };
return await _templates.RenderAsync(source, model);
}
}
For previews without real data, ITemplateEngine.CreateTestModelFor
can generate a model populated with dummy values.
Injecting into zones
A custom zone
tag lets modules inject content into well‑known spots inside a template:
{% zone 'order_items_before' %}
Subscribe to TemplateZoneRenderingEvent
to provide HTML or Liquid fragments for a zone:
public class ThankYouHandler : IConsumer<TemplateZoneRenderingEvent>
{
public Task HandleEventAsync(TemplateZoneRenderingEvent ev)
{
if (ev.ZoneName == "order_items_before")
{
ev.InjectContent("<p>Thank you for your order!</p>", parse: false);
}
return Task.CompletedTask;
}
}
Last updated
Was this helpful?