Umbraco 4.7 Razor Feature Walkthrough – Part 2

Thursday, February 24, 2011 by Gareth Evans

Part 2 of the feature walkthrough continues with features available in the TAFKA 4.6.2 release.
Today, i'm covering Macro Parameters, some fetching node helpers, and how to access media

Macro Parameters

You can now access parameters defined on the macro which invokes the macro.
Just like XSLT, if you define a macro parameter, you can then pass it from the Template to the Macro.

Please excuse the references to cats in the upcoming examples, cat pictures are ridiculously easy to find online and they make good examples when testing.

Given a parameter defined on the macro called animalName, you can access it in Razor like this:
@Parameter.Animalname => "cat"

The casing makes no difference here.

Culture specific strings are available too with @Dictionary

DynamicNode Constructors [string | int | object]

We've added constructors to DynamicNode that allow you to look up a node.
There's 3 overloads which take different types depending on what you have available to you at the time:

//a node that has it's id passed by QueryString
new DynamicNode(HttpContext.Current.Request.QueryString["id"]) //a node from a known hardcoded ID
new DynamicNode(1046)


When you define variables like this, you must declare them with the type dynamic:
e.g.

dynamic node = new DynamicNode(1046)


if you don't do this, Razor won't be able to find properties or methods on the new type

DynamicMedia vs Media Properties

In 4.6.1, working with media was a little difficult.
While it was easy to get the nodeId of the media item, you couldn't easily get access to the data of the media.

You could execute the new Media() constructor from the API but the readability wasn't quite right.

We've added a new type called DynamicMedia which can be used in two ways.

You can instantiate a DynamicMedia item with an id:

dynamic mediaItem = new DynamicMedia(1054);
@mediaItem.umbracoFile // => /path/to/media/item.jpg

or, from a DynamicNode, you can call the shorthand helper, .Media
There's two overloads for .Media
one just takes a property name for the property to return as DynamicMedia. You should use this syntax when you need to access multiple properties on the Media item

dynamic mediaItem = @item.Media("catPicture");
@mediaItem.umbracoFile
@mediaItem.comment //(assuming comment is defined as a property on your media type)

the second, allows you to quickly access a single property:

@item.Media("catPicture","umbracoFile")


Here's an example:

@ForEach(var item in @Model.Children) { 
<img src="@item.Media("catPicture","umbracoFile")" />

 

DynamicMedia ctor string,int,object)

Just like DynamicNode, there's a constructor that takes string, int or object and returns you a DynamicMedia
Internally, the method just takes whatever you give it and attempts to treat it as an int.
If an int is successfully obtained, you get a DynamicMedia instance.

DynamicNode .NodeById & .MediaById

As a shorthand, a slightly more readable syntax is available if you already have a DynamicNode
You can call .NodeById or .MediaById to get a DynamicNode or DynamicMedia.

These are just helpers on DynamicNode so that you don't have to remember to put them in dynamic to access properties.
Here's an example:

@Model.NodeById(1046).Name


Follow me at @agrath on twitter, and here's a few links:
The new Razor forum on our.umbraco: http://our.umbraco.org/forum/developers/razor
Codeplex for any feature requests or bugs: http://umbraco.codeplex.com/

Read more from the Umbraco Razor walkthrough series

Part 1
Part 2
Part 3
Part 4
Part 5
Part 6
Part 7
Part 8

7 comment(s) for “Umbraco 4.7 Razor Feature Walkthrough – Part 2”

  1. Gravatar ImageJeroen Breuer Says:

    If you use the Digibiz Advanced Media Picker you store the media xml in the umbraco.config file and also acces it easily with Razor.

    Topic with sample: http://our.umbraco.org/forum/developers/razor/17682-DynamicXml-not-working

    Package: http://our.umbraco.org/projects/backoffice-extensions/digibiz-advanced-media-picker

    Jeroen

  2. Gravatar Imagegliljas Says:

    Really nice! Keeping the DynamicMedia(1054) type constructor rubs me the wrong way, though... Is it really necessary?

  3. Gravatar ImageGareth Evans Says:

    The constructor is there because @Model is usually the Current node within the page - while @Model.NodeById(int) is perfectly valid and will work, some people may prefer the alternate syntax with the constructor so that it doesn't look like a child is being retrieved from the current node.

  4. Gravatar Imagegliljas Says:

    OK. I just think it's a bad practice to have fat constructors like that, performing potentially failing lookups etc. All pitfalls aside, it's a nonstandard use of a constructor. I would prefer DynamicMedia.GetById(int).

    Of course that would just hide the real bad guy, but still... :)

  5. Gravatar ImagePetr Snobelt Says:

    Agree with gliljas, change constructor to static factory methods.

  6. Gravatar ImageDan Diplo Says:

    I agree with gliljas a static factory method would be better. In fact, even better would be to use an instance of the TryParse patter so it would be:

    DynamicMedia media;

    if (DynamicMedia.TryParse(out media))
    {
    // do something
    }

  7. Gravatar ImageMike Says:

    This

    @item.Media("catPicture","umbracoFile")

    is redundant when (if) you can do this:

    @item.Media("catPicture").umbracoFile

Leave a comment