RazorEngine v2: Subtemplating

Subtemplating with @Include
ASP.NET MVC3 includes the Razor view engine, which was the starting point for the RazorEngine project. Razor views (like their WebForm counterparts) support the ability to include partial views in the parent view. In doing so, it allows you to modularise your views into logical sections.

Much like the Razor view engine, we also support this concept in RazorEngine. We’ve implemented partial view support using the @Include methods built into TemplateBase. We specifically haven’t named them RenderPartial (ala the Razor ViewEngine) as we want to differentiate RazorEngine from it’s MVC counterpart. So how do we start subtemplating?

Here is an example template:

Here is a sample template. @Include("helloWorld")
Code language: PHP (php)

When parsing this template, the Razor code generated creates the method calls to the TemplateBase methods. During execution, these methods will first determine if the template named “helloWorld” has been pre-compiled (and as such exists in the current TemplateService’s template cache.

We can handle the resolution of this named template two ways:

string helloWorldTemplate = "Hello World"; Razor.Compile(helloWorldTemplate, "helloWorld"); string fullTemplate = "Here is a sample template. @Include(\"helloWorld\")"; string result = Razor.Parse(fullTemplate);
Code language: JavaScript (javascript)

In the above example, we are precompiling the template ahead of time. This enforces the template is cached (all compiled templates are named). If we don’t want to precompile the template, we need a ITemplateResolver.

Razor.AddResolver(s => GetTemplateContent(s)); string fullTemplate = "Here is a sample template. @Include(\"helloWorld\")"; string result = Razor.Parse(fullTemplate);
Code language: JavaScript (javascript)

By adding a resolver, it allows us to dynamically locate the template which hasn’t been precompiled. This template is then compiled, executed and the result is injected into the result of the parent template. An ITemplateResolver is defined as:

public interface ITemplateResolver { string GetTemplate(string name); }
Code language: PHP (php)

The result of the template resolver must be the unparsed template content. RazorEngine supports adding multiple template resolvers to a TemplateService, as well as declaring a template resolver though a Func instance.

Passing Models from Parent to Child
RazorEngine also supports passing model data from a parent model to a child model using @Include(templateName, model). Child models are treated in compilation the same way as parent models.

string helloWorldTemplate = "Hello @Model"; Razor.CompileWithAnonymous(helloWorldTemplate, "helloWorld"); string fullTemplate = "@Include(\"helloWorld\", @Model.Name)! Welcome to Razor!"; string result = Razor.Parse(fullTemplate, new { Name = "World" });
Code language: JavaScript (javascript)

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Post