Tuesday, March 1, 2011

Umbraco Razor Feature Walkthrough – Part 4

Part 4 of the feature walkthrough continues with features available in the TAFKA 4.6.2 release.
Today, I'm covering .Where to filter nodes and .OrderBy to order nodes

RC1 is just around the corner and there's a bunch more features coming - i'll try and cover those too when they come out -
We've got more functions for navigating your tree, slightly better support for some .Where edge cases, .Where extension methods and more!


Taking this implementation to the next level, we quickly found we wanted to select a random number of elements which should be visible but were still published.
An example is if you have a boolean property (defined as the True/False data type) on your document type that indicates if an item should be featured or not.

With DynamicObject (DynamicNode too, because it inherits from), the c# compiler / razor parser doesn't allow you to use the familiar lambda syntax to filter your sets.
This is because we now return a DynamicObject [DynamicNodeList] to allow method chaining.

This will not work in 4.6.1 or 4.7.

@Model.Children.Where(item => item.shouldBeFeatured); //Lambda's cannot be used against Dynamic Objects 

With the new 4.7 syntax, you can now use .Where to filter your nodesets.
To do this, we took the string parser from the 2008 linq samples and then added support for working with DynamicObjects

I saved the best for last!

A simplistic filter by a single boolean:


A longhand filter, demonstrating the equality operator and type safety:

@Model.Children.Where("shouldBeFeatured == true") 

Using NotEquals:

@Model.Children.Where("shouldBeFeatured != true") 

Using GreaterThan against a numeric property

@Model.Children.Where("catCount > 1") 

Using Modulus (to get the remainder of a number)
(will return any children where the number of cats is even)

@Model.Children.Where("catCount % 2 == 0") 

Using string comparisons and boolean logic (|| [or], && [and]) - also shows how to nest strings

@Model.Children.Where("menuType == \"Top Menu\ || menuType == \"Bottom Menu\"") 

Chaining into your own extension method
(will return 8 randomly selected nodes which are marked as featured items)


Passing Variables from outer scope into the .Where expression:
If you need to access a variable from outside the scope (e.g. a number etc) and don't want to pass it as a constant,

var maxLevelForSitemap = 4; var values = new Dictionary<string,object>(); values.Add("maxLevelForSitemap", maxLevelForSitemap) ; var items = node.Children.Where("ShouldBeVisible == true && Level <= maxLevelForSitemap", values); 


We have also added support for OrderBy, this lets you sort your nodesets by the properties on the nodes themselves.

Simplistic ordering by a single property:


More complex ordering by multiple properties, with descending/ascending support:

@Model.Children.OrderBy("catCount, colour desc") 

Warning: There's a small bug in the 4.7 beta which means you can't order by a single descending column. This is fixed in RC1.


That pretty much wraps up my additions to Razor in 4.7beta, hopefully the new syntax improves your ability to work with razor to build websites with umbraco :)
Some more parts to come once the RC is released

I'm Gareth Evans, Follow me at @agrath on twitter, and here's a few links:
The new Razor forum on our.umbraco
Github for any feature requests or bugs

Read more from the Umbraco Razor walkthrough series

Umbraco Razor Feature Walkthrough - Part 1
Umbraco Razor Feature Walkthrough - Part 2
Umbraco Razor Feature Walkthrough - Part 3
Umbraco Razor Feature Walkthrough - Part 4
Umbraco Razor Feature Walkthrough - Part 5
Umbraco Razor Feature Walkthrough - Part 6
Umbraco Razor Feature Walkthrough - Part 7
Umbraco Razor Feature Walkthrough - Part 8

Want to be updated on everything Umbraco?

Sign up for the Umbraco newsletter and get the latest news and special offers send directly to your inbox