mandag den 3. marts 2014

Adding new renderings to an item from code

Starting with Sitecore 6.4 and forward, renderings in Sitecore is saved as deltas (differences between the standard values and the "full" rendering) on the item.

This means, that we need to do some work if we want to read, change and save the renderings.

Here is how to both read the renderings, and how to save the deltas back to the item:

public static IEnumerable<RenderingDefinition> GetRenderings(Item item, DeviceItem device)
{
    string xmlLayout = XmlDeltas.GetFieldValue(item.Fields[FieldIDs.LayoutField], XmlDeltas.WithEmptyValue("<r />"));

    LayoutDefinition layoutDefinition = LayoutDefinition.Parse(xmlLayout);
    DeviceDefinition deviceDefinition = layoutDefinition.GetDevice(device.ID.ToString());

    return deviceDefinition.Renderings.ToArray().Cast<RenderingDefinition>();
}

By using the GetFieldValue on the XmlDeltas class, we get the combined layout from the standard values combined with the delta.

Now, to be able to add a new definition to the item, here is what you have to do:

public static void InsertRendering(Item item, DeviceItem device, int index, RenderingDefinition rendering)
{
    string xmlLayout = XmlDeltas.GetFieldValue(item.Fields[FieldIDs.LayoutField], XmlDeltas.WithEmptyValue("<r />"));

    LayoutDefinition layoutDefinition = LayoutDefinition.Parse(xmlLayout);
    DeviceDefinition deviceDefinition = layoutDefinition.GetDevice(device.ID.ToString());

    deviceDefinition.Insert(index, rendering);

    using (new EditContext(item))
    {
        XmlDeltas.SetFieldValue(item.Fields[FieldIDs.LayoutField], layoutDefinition.ToXml());
    }
}

Here we get the definition for the specified device, and just insert the rendering into the passed index, moving the other renderings down the list.

Finally we edit the item, and tells it to set the value of the layout field on the item to the xml defining the entire layout.

The secret is in how SetFieldValue works, since it, behind the scenes, generates the delta between the standard values and the passed xml, and only saves that to the item.

Using this as the base, will allow you to change the renderings, since you can use the same logic to create a ChangeRendering function.

Ingen kommentarer:

Send en kommentar