@import directive for helpers

Apr 27, 2011 at 8:45 PM

Hi,

I have implemented a solution  to make reusable components of function helpers. It is a very common scenario to be able to call from different template files the same functions to render part of a document.

For example, suppose I have a function "PrintSection" defined in a separate template called "Tools":

@model MyApp.MyMContext
@helper PrintSection(string name, string content) {
<div class="section">
    <h1 class="title">@name</h1>
    <div class="content">
        @content
    </div>
</div>
}

I can import this function in another template like this, by using the Import directive and access through the Helpers property:

 

@model MyApp.MyContext
@Import("Tools", @Model)

@foreach(var section in @Model.Sections) {
   @Helpers.Tools.PrintSection(section.Name, section.Content)
}

 

Internally, I'm using a subclass of TemplateBase<T> that is providing a dynamic object through the property "Helpers" (which is a System.Dynamic.ExpandoObject).

When an Import is perform, the function is resolving the template, and gets all the helper methods that return a TemplateWriter.

Then a dynamic property on "Helpers" is created with the name of the import ("Tools"). This dynamic property is linked to a custom DynamicObject that is redirecting calls to the proper helpers methods.

This way, it's very easy to reuse methods declared from other templates.

Currently, there is only a small drawbacks in the internals, since I need to resolve a template (similar to include directive), but I don't have access to such method, so I had to go through reflection to get them.

One suggestion could be to expose for the TemplateService class a method to resolve external templates without executing it, a public method like this:

public ITemplate ResolveTemplate<TModel>(string name, TModel model)

This solution is probably not the only one. What do you think about it? Do you think you could provide a public resolver for a template (I don't think It hurts the current design, but It helps to build similar methods to Includes).

I can post this solution as a patch if you are interested in.

Dec 30, 2014 at 2:59 PM
Hi alexandre_mutel,

I'm really interested about this solution. I'm working with razorengine 3.3.0.0 and need to call shared templates. Could you share your solution please ?

Thanks

Freddy
Jan 4, 2015 at 1:54 AM
frederyck wrote:
I'm really interested about this solution. I'm working with razorengine 3.3.0.0 and need to call shared templates. Could you share your solution please ?
I don't have a solution out-of-the-box. I moved away from razorengine and create my own lightweight razor wrapper called SharpRazor and using it in SharpDoc (where I have implemented the import directive there)