Sitecore Rendering Parameters Primer: Part 1

Abstract

If you aren't using Rendering Parameters with your Presentation Components you're missing out on a fundamental aspect of Sitecore that will truly allow you to separate code from content and change the way your Page Designers interact with your presentation components.

Overview

As software craftsmen, we often go out of our way communicating and exemplifying the need to separate code from data. Separation of Concerns, after all, is one of fundamental tenets we try to enforce to ensure that our code is testable, maintainable and changeable. It is very common with Sitecore implementations, for Presentation attributes to find themselves added to content templates. Attributes such as "Hidden" or "Size" are commonly used to give Page Designers the flexibility they need to achieve some goal in the presentation of content. Based on the values of these types of attributes, we'll typically find some conditional behavior in the Renderings that visualize the content. These types of attributes don't truly belong in the content templates as they do not describe the content type, only how to render it.

To make the distinction more clear between Content and Presentation concerns, I prefer to use the monikers "Data Template" and "Presentation Template". Based on these naming conventions we can then state that Data Templates focus on the "What" and Presentation Templates focus on the "How".

The "Title Size" attribute

For example, a component may be built to show a content item's title. Requirements later change and the system must now support specifying a size (Small, Medium, Large). If you're relatively new to Sitecore, your first inclination will be to add an attribute to the content template and call it "Title Size". Remembering your training from Sitecore Developer Certification, you'll probably add Simple Text elements under a node called "Title Size" representing Small, Medium and Large and then use these as Drop List values for your Title Size field. In your code-behind, you'll then probably use some code such as:

var size = Sitecore.Context.Item["Title Size"]; var sizeClass = "title-medium"; switch (size) { case "Small" : sizeClass = "title-small"; break; case "Medium": sizeClass = "title-medium"; break; case "Large": sizeClass = "title-large"; break; default: break; } TitleText.CssClass = sizeClass;

While most would agree that this design is acceptable, there are a couple of inherent problems with this approach. First, we are mixing presentation details with our content. Second, we are hard-coding CSS classes in our code and our code doesn't support change. If we were to introduce an Extra Large size, we'd need to change our code to support it. A small re-factoring eliminates the second problem. We'll redefine our Basic Text content type and provide a "Value" field for them. Second, we'll change the field type for the title template from DropList to DropLink so we can get a reference to the item and read its Value field.

Rewriting the code we now have:

var size = Sitecore.Context.Item["Title Size"]; var sizeClass = "title-medium"; if ( !string.IsNullOrEmpty(size) ){ sizeClass = new Item(new ID(size))["Value"]; } TitleText.CssClass = sizeClass;

We now have a very flexible design. As new title size classes are defined (or changed), we can very easily keep the content items supporting these sizes in synch. Adding an Extra Large size now only requires the addition of a class in CSS and an additional content item containing the name "Extra Large" and the value "title-extra-large". This design still doesn't satisfy our need to keep content and presentation details separate. Sitecore provides out-of-box support for this in the form of Rendering Parameters. When a presentation component is selected and placed on a Layout in the Page Editor an option exists to modify component properties. These properties, among other things, allow a Page Designer to specify an alternate data source (other than the context item) as well as a number of freeform name/value pairs. These name/value pairs are located under the data section heading "Parameters".

When editing component properties through Page Editor, the Parameters section can be used to specify additional key/value pairs for a given rendering. In our example, we're going to define a parameter called "TitleSize". The Title Size parameter will be further defined as having acceptable values of "Small", "Medium", "Large" and "Extra Large".

To access these parameters, we now need to modify our code-behind to read the parameters.

string rawParameters = Attributes["sc_parameters"]; var parameters = Sitecore.Web.WebUtil.ParseUrlParameters(rawParameters); var size = parameters["TitleSize"]; var sizeClass = "title-medium"; switch (size) { case "Small" : sizeClass = "title-small"; break; case "Medium": sizeClass = "title-medium"; break; case "Large": sizeClass = "title-large"; break; case "Extra Large": sizeClass = "title-xlarge"; break; default: break; } TitleText.CssClass = sizeClass;

When Sitecore instantiates and adds a rendering to a Layout, Sitecore takes all the component properties, encodes them and passes them to the rendering in Attributes collection with the key "sc_parameters". Sitecore's WebUtil class has a built in method called "ParseUrlParameters" that will separate each key/value pair into a Name Value Collection. The values can then be accessed using the NameValueCollection's indexer. We have effectively cleaned up our Content Template by removing Presentation concerns and placing them where they belong, with the presentation components. Content Authors can focus on the What (the content) and Page Designers can focus on the How (the presentation).

This still isn't quite good enough though. Using the Parameters section for rendering parameters is risky at best. The parameter name could be misspelled, as could the value. In the event the value is an identifier for an item, the training necessary to ensure that item IDs or their paths are copied and pasted correctly is painful. As the developers on Sitecore, our job is to make life as easy as possible for the Content Authors and Page Designers. To accomplish this, we need to make a change to provide "strongly typed" parameters for the rendering. To do this, we'll create a new content template called "Title Sublayout Rendering Parameters". We need to change our base template for this content type from "Standard Template" to a special template used for extending the component properties dialog. This template called "Standard Rendering Parameters" is found under templates/system/layout/rendering parameters. Once we've changed our base template out, we can now create our Field "Title Size". We'll adopt the same strategy from our 2nd attempt above and define Title Size as a Drop Link. The data source for the drop link will point to a list of Title Size items. Finally, we need to modify our Title Sub Layout and specify a rendering template for it.

Set the "Parameters Template" field to the "Title Sublayout Rendering Parameters". Optionally, you can also change "Open Properties After Add" to "Yes" and Sitecore will automatically open the component properties dialog when the title sublayout control is initially dropped on the presentation.

When a Page Designer opens the Title component properties they will now see the following:

Note that a Page Designer can now choose which Title Size they want to apply. The new Title Size attribute is accessible in the same way it was when we used raw parameters, through the sc_parameters attribute. As new title sizes are added or existing ones are modified, a Developer or Page Designer can make the changes and avoid the need to do a build. We'll dig deeper into using rendering parameters for the specific purpose of supporting my favorite CSS framework, Twitter Bootstrap in Part 2.

Summary

We just developed 3 different ways to provide support for specifying size for a title. The key takeaway from the examples above is two-fold: First, effective use of lists of values stored in the content tree simplifies life for Designers and Authors. Second, the use of rendering parameters for renderings helps promote separation of concerns, keeping data templates specific to data and rendering templates specific to presentation. You'll discover that it is much easier as you start to use Rendering Parameters if you refer to your content templates as Data Templates and remember that they need only specify the "What" and should almost never specify the "How". The "How" should be covered using Presentation Templates which Sitecore refers to in its documentation as Rendering Parameters.