Level: 300
 

Programmatically set layouts in Sitecore

c# code

In some cases like when importing content or similar, you might need to set layouts on items or standard values programmatically. In this article we will go through an example, where you will learn how to configure both layouts and renderings on a given item.

 

 

Written by: Jens Mikkelsen
Thu, Jul 7 2011

The layout field in Sitecore has a nice UI showing the different presentation components on a given item. For instance you can go to the standard values of the sample template and see the following in a clean installation of Sitecore:

 

Layout field in Sitecore

 

However if you click the “Raw values” checkbox in the “View” tab, you will see the data behind the UI isn’t that straight forward to understand. It is XML and looks something like this:

 

< r xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  < d id = "{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}" l="{14030E9F-CE92-49C6-AD87-7D49B50E42EA}">

    < r ds = "" id="{885B8314-7D8C-4CBB-8000-01421EA8F406}" par="" ph="main" uid="{43222D12-08C9-453B-AE96-D406EBB95126}"/>

    < r ds = "" id="{CE4ADCFB-7990-4980-83FB-A00C1E3673DB}" par="" ph="/main/centercolumn" uid="{CF044AD9-0332-407A-ABDE-587214A2C808}"/>

    < r ds = "" id="{493B3A83-0FA7-4484-8FC9-4680991CF743}" par="" ph="/main/centercolumn/content" uid="{B343725A-3A93-446E-A9C8-3A2CBD3DB489}"/>

  </ d >

  < d id = "{46D2F427-4CE5-4E1F-BA10-EF3636F43534}" l="{14030E9F-CE92-49C6-AD87-7D49B50E42EA}">

   < r ds = "" id="{493B3A83-0FA7-4484-8FC9-4680991CF743}" par="" ph="content" uid="{A08C9132-DBD1-474F-A2CA-6CA26A4AA650}"/>

  </ d >

</ r >

 

In this XML everything that Sitecore needs to render a page is specified. This includes the layout, sublyouts, renderings as well as placeholder information etc.


So do you need to construct this yourself, is you are to specify it programmatically? Certainly not! You can configure all the presentation information using the Sitecore API. However it may be a little opaque how to do it to start out with, you’ll soon get the hang of it.

 

The code

In this example we will take a sample item, and set the sample layout and sample rendering as presentation components on the default device. Please note that it is best practice to set presentations on Standard values as described here.


When you need to handle presentations in Sitecore you need to work with the class Sitecore.Layouts.LayoutDefinition. It is this class which converts the presentations to and from XML, which can be stored in the presentation field of the item.


So the first thing we need to do is get hold of the item, we want to operate on, and load the current settings. Please note that you should operate on the master database, if you want to set any values. Further you should probably use the SecurityDisabler to overwrite any Sitecore security settings, which might disable you to alter the item. So the first part should look something like this:

 

//Use the security disabler to ensure you can alter content

using (new SecurityDisabler())

{

  //Get the master database

  Database masterDatabase = Database.GetDatabase("master");

  //Get the item we want to operate on

  Item sampleItem = masterDatabase.GetItem("/sitecore/content/home/Sample item");

 

So now we got the item. Now we need to get the LayoutDefinition by getting the value from the presentation field of the item. The presentation field is called __Renderings.

 

  //Get the value of the __renderings field

  string renderingXml = sampleItem["__Renderings"];

  //Create a LayoutDefinition and load in the XML

  LayoutDefinition layoutDefinition = new LayoutDefinition();

  layoutDefinition.LoadXml(renderingXml);


As you may or may not know, Sitecore operates with multiple devices, which allows you to define different presentation components depending on which device is resolved in the Context. As mentioned earlier, we are going to operate on the Default device, so we are going to pull that out of the LayoutDefinition:

 

  //This is the id of the default device

  //Note that this part of the API takes in a string and not an ID

  string defaultDeviceId = "{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}";

  //Get the default device on the LayoutDefinition

  DeviceDefinition deviceDefinition = layoutDefinition.GetDevice(defaultDeviceId);

 

The DeviceDefinition holds all the specifics on what presentations are added to the specific device. So here we can set the Layout we want and later add renderings and sublayouts:

 

  //The sample layout id (again as a string)

  string sampleLayoutId = "{14030E9F-CE92-49C6-AD87-7D49B50E42EA}";

  //The layout is set by the Layout property

  deviceDefinition.Layout = sampleLayoutId;

 

Now we have added the layout but we also want to add the rendering. This is done by adding one or more RenderingDefinition’s on the DeviceDefinition. You can add several presentations to this:

 

  //The sample rendering id (again as a string)

  string sampleRenderingId = "{493B3A83-0FA7-4484-8FC9-4680991CF743}";

  //Create a RenderingDefinition and add the reference

  RenderingDefinition renderingDefinition = new RenderingDefinition();

  renderingDefinition.ItemID = sampleRenderingId;

  //Set which placeholder the rendering should be shown in

  renderingDefinition.Placeholder = "content";

  //Add the RenderingReference to the DeviceDefinition

  deviceDefinition.AddRendering(renderingDefinition);


All the values have been stored in the LayoutDefinition, so now all we need to do is to convert it to XML and save it in the __Rendedrings field:

 

  //Convert the settings to XML

  string outputXml = layoutDefinition.ToXml();

  //Store it in the renderings field

  sampleItem.Editing.BeginEdit();

  sampleItem["__Renderings"] = outputXml;

  sampleItem.Editing.EndEdit();

 

That is it. You have now programmatically set the presentation for the sample item.

 

 

 

 

 

 

Please rate this article


7 rates / 3,86 avg.

  • Jens Mikkelsen

    About the author:

    Jens Mikkelsen

    Jens Mikkelsen is a partner at Inmento Solutions a Sitecore consulting firm. He works as a Sitecore specialist and consulting helping clients architect and build quality Sitecore solutions using the newest modules and tools. 

    Further he has been deeply envolved in various complex solutions and has built up a strong knowledge of Sitecore architecture and best practices. He has especially focused on and is specialized in debugging and analyzing Sitecore solutions.

     

    Jens is very interested in the technical mechanisms in the new marketing products such as Sitecore DMS and Sitecore ECM.

7 responses to "Programmatically set layouts in Sitecore"

Hi Jens ..again i need your help ........ I am Using Sitecore 6.5 and i want add Marketer modules forms programmatic on Domain contents . I am using placeholder on layouts for associating manually Marketer Module forms ,its doing well but i want do all these work programmatic . Thanks
Posted: Friday, July 15, 2011 7:47 AM
test
Posted: Wednesday, January 11, 2012 5:10 PM
Hi

How Can we add TestLab Navigation in Control Property Window in SiteCore.

http://stackoverflow.com/questions/10510772/add-testlab-navigation-in-control-property-window-in-sitecore
Posted: Wednesday, May 09, 2012 8:33 AM
I tried to add a rendering to an item and noticed that I have always overwritten the existing ones (inherited from standard values or directly assigned).
As I think, many will have this problem and I just got a solution from the support, I will just shortly document it here:

instead of using this (than cannot read the Renderings in my example):
LayoutDefinition layoutDefinition = new LayoutDefinition();
layoutDefinition.LoadXml(renderingXml);

use this:
LayoutDefinition layoutDefinition = LayoutDefinition.Parse(renderingXml);

this way you can access and modify the renderings...

also - as mentioned somewhere else on the web:
use this to write back to the field (it will make sure, that only the differences to the standard values gete saved to the item):
LayoutField layoutField = item.Fields[Sitecore.FieldIDs.LayoutField];
layoutField.Value = outputXml;

I hope this helps to save some time ;)
Posted: Thursday, August 30, 2012 3:20 PM
This blog needs some spam control. Something like akismet for wordpress.
Posted: Wednesday, April 03, 2013 6:00 PM
Hi Jens,

Another great article, thank you. One thing I've noticed recently is that the following code to read the layout xml doesn't work with our website which is 6.6 update-6:

//Get the value of the __renderings field
string renderingXml = sampleItem["__Renderings"];
//Create a LayoutDefinition and load in the XML
LayoutDefinition layoutDefinition = new LayoutDefinition();
layoutDefinition.LoadXml(renderingXml);

It may be to do with how the layout deltas are now processed but the layoutDefinition ends up with mostly null properties including the Layout field and an empty renderings array. Instead we first use the LayoutField as follows and all works as expected:

var layoutField = LayoutField.GetFieldValue(item.Fields[Sitecore.FieldIDs.LayoutField]);
if (string.IsNullOrEmpty(layoutField))
{
return;
}

var layoutDefinition = LayoutDefinition.Parse(layoutField);

Hope this helps someone out.

David
Posted: Friday, June 21, 2013 10:38 AM
It seems we need some diagram to remember how to fill up the placeholder with rendering :)
Posted: Wednesday, April 09, 2014 4:23 PM

Leave a reply


Notify me of follow-up comments via email.
 
 
#nbsp;