Using Razor in Umbraco 4

If you've been following the development of Umbraco Juno (4.6) you'll have seen that Niels released an add-in for early Juno builds to which was for working with Razor, the new syntax for ASP.Net development.

Well here's something even more exciting, Umbraco Juno no longer requires an add-in, instead it has a out-of-the-box support for working with Razor!

AWESOME!

Umbraco <3 Razor

So what does the Razor support for Umbraco include? Well basically it allows Razor to be used in the same way that you use the Iron* languages, XSLT or .NET controls... as a macro. This means that you can use Razor just as you would any other language option.

Working with Razor in Umbraco

So if you want to work with Razor what do you need to do? Well creating a Razor macro is just as nice as if you're doing any other kind of macro, through the Umbraco UI.

Razor files live along side the Iron* files in the /python folder (yeah, that's a hold over from the original DLR engine and changing it would be a breaking change so we have to live with it. Note - as Morten pointed out in the comments you can set <add key="umbracoPythonPath" value="~/Razor" /> and use a different path for script files), and you create them like you create any other DLR script file in the Umbraco back office:

Create Razor macors

(Yes there's a spelling error in the beta which I've fixed :P)

Now you can start coding up your Razor macros.

My first Razor macro

With Razor macros there's a slightly different way that you go about it, rather than using currentPage as you would with XSLT or an Iron* script you have a Model property which you work with.

To make this a bit nicer as well the Model property is a dynamic object, allowing you to access the properties as if they were actually properties of the model, meaning you can do this following:

<div id="content">@Model.bodyText</div>

That's how easy it is to access the properties of the Model, no more getProperty("bodyText").Value. And there you have it, a basic Razor macro has been created.

Something a bit more advanced

Well lets take it up a notch and make a slightly more advanced macro, say a news listing:

<div class="news-lissting">
	@foreach(var page in Model.Children) {
		<div class="news-item">
			<h2><a href="@page.Url" title="@page.Name">@page.Name</a></h2>
			<h3>Published: @page.articleDate.ToString("dd MMM yyyy")</h3>
			<p>@page.description<p>
		</div>
	}
</div>

What we're doing here looping through each of the children of the current page (the Model), and generating a <div> and then creating the HTML structure inside it.

Post-beta features

Just a little note I've added a change to the DynamicNode class which is used by the dynamic Model object that allows you to access specific types of children, so you can do this in your Razor file:

<div class="news-lissting">
	@foreach(var page in Model.articles) {
		<div class="news-item">
			<h2><a href="@page.Url" title="@page.Name">@page.Name</a></h2>
			<h3>Published: @page.articleDate.ToString("dd MMM yyyy")</h3>
			<p>@page.description<p>
		</div>
	}
</div>

In this example my Model has children of the type article (that's the alias of the DocType) and I'm requesting them all (hence the pluralization). Pretty sweet I think!

Conclusion

I'm sure that even the most seasoned XSLT "developer" (I'm looking at you Warren!) will have to admit the Razor syntax is highly readable for people who aren't .NET developers. And because we're working with a dynamic object it's really simple to access the properties as needed.

This brings us to the end of our quick look at the Razor support which is coming in Umbraco Juno, and how it's going to be another great choice for developers.

umbracorazor
Posted by: Aaron Powell
Last revised: 27 Dec, 2010 11:00 AM History

Trackbacks

Comments

Adamsimsy
Adamsimsy
23 Feb, 2011 09:43 AM

Is it possible to include Razor views using the following:

@Html.Partial("_CommonHeader")

I'm hoping to add these includes in the main template instead of including Macros.

Mark
Mark
01 Feb, 2011 04:18 PM

It's working for me now. It was an issue with case. I had to use:

@foreach(var page in Model.Slideshows) {

and then it worked. The strange part was that my doctype was defined with an alias of 'slideshow' (all lowercase). I went ahead and changed the doctype alias to 'SlideShow' so that it matches my Razor code and its still working. I don't fully understand why but glad its working now.

Thanks!

Mark
Mark
31 Jan, 2011 10:08 PM

Thanks for the great writeup!. I am having trouble getting the feature where you request children of a specific doctype to work.

I have a foreach like this:

@foreach(var page in Model.slideshows) {

and I have children with a doctype of "slideshow"

but I keep getting the error:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'umbraco.MacroEngines.DynamicNode' does not contain a definition for 'slideshow' at CallSite.Target(Closure , CallSite , Object ) at System.Dynamic.UpdateDelegates.UpdateAndExecute1....

Any ideas what I am doing wrong? Thanks!

31 Jan, 2011 10:11 PM

Do you have children of type 'slideshow' under that node?

I think it handles pluralization, I'm pretty sure I added it at new years

Jonas Eriksson
Jonas Eriksson
15 Jan, 2011 01:36 PM

Hi, this is really great. How about the macro parameters, can they also be included (are they already)?

Jannick
Jannick
07 Jan, 2011 01:03 PM

Where can I see what properties etc. are available on the dynamic Model object? I mean, I can see you can call Model.Children - but is there a overview somewhere?

07 Jan, 2011 03:15 PM

Will Do Umbraco 4.6 full support Razor features or not?

07 Jan, 2011 10:24 PM

@Jannick - the Model implements all the properties and methods of the NodeFactory Node class, with all the aliases being accessible as properties.

@Biagio - what do you mean by 'full Razor features'?

06 Jan, 2011 06:32 AM

Wow ! I can't wait to use Razor on release mode. Thanks for the nice article

21 Jan, 2011 10:53 AM

Yes, I would also like to know about how to read macro parameters in Razor syntax? I googled but could not find any thing worth for this.

27 Dec, 2010 08:35 AM

Awesome guide! Remember that you can also use inline Razor in templates like this:

@Model.Name

I'll be adding caching for RC so you can specify that as an attribute...

27 Dec, 2010 08:39 AM

Cool! Thanks for sharing this guide.

/Fredrik

27 Dec, 2010 08:56 AM

Just a little side note: You could change the name of the "python"-folder to i.e. "Razor" by adding the following appsetting to the web.config: might make more sense if you were only going to use it for razor macros.

Thanks for writing this!

Btw what about Intellisense support in VS?

Roland
Roland
27 Dec, 2010 09:09 AM

Cool and thanks for sharing :D

27 Dec, 2010 09:12 AM

@slace: Looks like tags doesn't get encoded in comments - my Razor comment didn't made any sense at least - here's how:

<umbraco:Macro runat="server" language="razor">
   @Model.Name
</umbraco:Macro>
27 Dec, 2010 09:29 AM

Hope caching will be back soon. It's really slow without. It was there in the pre beta package though, so hope it'll be back soon.

Also could you post an example with importing a namespace, couldn't get that to work pre beta and hope that changed, would be great.

Roland
Roland
27 Dec, 2010 10:20 AM

Morten,

What do we have to add into the web.config to use a Razor folder instead of that of Python?

27 Dec, 2010 10:51 AM

Oh yeah, forgot you can override the config settings, thanks Morten.

Here's the config value he's referring to:

<add key="umbracoPythonPath" value="~/Razor" />

FYI - this is a markdown editor not a RTE, code must be formatted ;)

27 Dec, 2010 07:01 PM

hmm... another syntax to learn? Or what? :-) What are the reasons to use Razor compared to XSLT? As i see it right now (I'm totally new to Razor), it's a question of syntax, readable code and intellisense. Or maybe some more advanced things can be done with Razor that can't be done with XSLT?

27 Dec, 2010 09:44 PM

Anders Lund

It comes down to a personal preference really, but keep in mind that as Umbraco 5 is a move to MVC3, Razor will be featuring quite prominently in the future of Umbraco.

JT
JT
28 Dec, 2010 01:32 AM

@Anders: see ScottGu's intro to Razor on his blog (though note that the engine has matured since then). Also check out his other posts tagged Razor to get a handle on the reasoning behind the language, its strengths and weaknesses.

I simply cannot wait to get my hands dirty with Razor support for Umbraco. It's a match that makes a lot of sense, and the syntax is a breath of fresh air in comparison to XSLT.

Don't get me wrong: I like XSLT, but it gets clunky very quickly.

28 Dec, 2010 02:01 AM

Great to see support for Razor in 4.6! Love it!

Its going to take a lot for me to move away from XSLT, but for those times when a quick macro is needed to output/format your content - Razor is looking ideal!

Also, really looking forward to the inline template syntax (via the 'language' attribute) - that's a killer feature!

Cheers, Lee.

28 Dec, 2010 11:04 AM

Hey, thanks for your answers.

I see that it might be down to personal preference, but I have read some more about Razor (after i saw this post), and it seems like its gonna be a big part of future ASP.NET - and of course now Umbraco.

Now we can't ignore that. I just hope that Razor will be easy to adapt to. I remember that I had a hard time some years ago with XSLT - and I understand that I'm not the only one :-)

blog comments powered by Disqus