Nice and simple Razor templates with the help of RenderPage and some dynamic sugar

Besides saving global helpers in App_Code we have the option to use RenderPage (or Html.Partial) in Razor to reuse code globally.

Both ways helps in making the HTML code DRY and well structured. But an important difference is a RenderPage file can be wherever we want, and changes are fluent (no app restarts). We do loose strongly typed parameters but I think that is a small price to pay when we are doing Html functions. We can still send a typed viewmodel to the rendered page. What about performance? As far as I understand we will get a performance hit the first time we call the page after a save (generally much quicker than a app restart tho). But after that it’s on par with a global helper. Correct me if I’m wrong.

This is the basic syntax :

@RenderPage("/path/to/SomeTypedView.cshtml",someObject)

And in the SomeTypedView.cshtml :

@{var viewModel = (SomeType)PageData[0]; // mimic strongly typed view}
<div="phew">@viewModel.Name</div>

But the RenderPage-code is rather ugly. Let’s make a small global helper to make the syntax nicer:
/App_Code/Tmpl.cshtml:

@helper Display(object value, string templateName="") {
    if (templateName=="") {
        templateName = value.GetType().Name;
    }
    @PageContext.Page.RenderPage("~/Shared/DisplayTemplates/" + templateName + ".cshtml",value)    
}

It’s using a defined path. And it also checks the type name if we do not specify it. So the two following instructions makes the same result:

@{var myObj = new MyType();}
@Tmpl.Display(myObj,"MyType")
@Tmpl.Display(myObj)

They both renders /Shared/DisplayTemplates/MyType.cshtml

Introducing RazorTemplates

Can we extend this further, using dynamics to write:

@tmpl.MyTemplateName(someModel)

…as a way to render the /DisplayTemplates/MyTemplateName.cshtml with someModel ?

Yes we can, check out DynamicHtmlTemplates in this gist, [Update: or the Umbraco RazorTemplates package which is basically the same, but evolved a little bit to an Umbraco context – also automatically picking up NodeTypeAlias to render file according to document type.]

Put DynamicHtmlTemplates in your App_Code and you can use:

DynamicRender

Cool eh?

@using DynamicHtmlTemplates
@{
 var myobj = new MyClass{Name="Someone", Value="123"};   
 dynamic tmpl = new Templates();
 // or dynamic tmpl = new Templates("~/Path/ToTemplates/");
 // or dynamic tmpl = new Templates("SubPathToTemplates");
}
        
Rendering /DisplayTemplates/MyClass.cshtml (sending myobj to PageData[0])
@tmpl.Display(myobj)

Rendering /DisplayTemplates/MyClassAlternative.cshtml  (sending myobj to PageData[0])
@tmpl.Display(myobj, "MyClassAlternative")
        
... or let it use Dynamic to figure out the template name:
Rendering /DisplayTemplates/MyClassAlternative.cshtml  (sending myobj to PageData[0])
@tmpl.MyClass(myobj)

Rendering /DisplayTemplates/MyClassAlternative.cshtml  (sending myobj to PageData[0])
@tmpl.MyClassAlternative(myobj)
        
Rendering /DisplayTemplates/Possible.cshtml (sending inline razor item template to PageData[0] and list to PageData[1])
@tmpl.Possible(Templates.ItemTemplate(@<text>this is @item</text>),new List<string>{"one","two"})

Contents of /DisplayTemlpate/Possible.cshtml:        
<div>
    @foreach(var item in PageData[1]) {
        @PageData[0](item)
    }
</div>

So with this, a bootstrap form can be created in a much more DRY way:
bootstrap

Tested in Umbraco 4.71 and Umbraco 6.02 as well as a vanilla WebPages site

Advertisements

2 thoughts on “Nice and simple Razor templates with the help of RenderPage and some dynamic sugar

  1. Funny Or Die separates itself from other funny video
    clip hosting sites by the way it lets people rank the videos, get enough
    funny votes and the video will be immortalized get enough die votes and the video will be sent into the “crypt”.
    The table top radio connects to the internet using Wi-Fi or Ethernet cable, and searches for stations by country, genre or call letters.
    Turn on iheartradio and then look at a different app, your station will keep playing and you can control everything from the “running apps” menu (double-click the
    home button).

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s