8

I need to programmatically update all of the instances of a particular rendering attached to a Sitecore item.

This is the code I first tried and failed to use:

foreach (RenderingReference renderingReference in parentRenderingReferences)
{
    /* ... unrelated code removed ... */
    var layoutField = new LayoutField(contentItem.Fields[FieldIDs.LayoutField]);
    LayoutDefinition layoutDef = LayoutDefinition.Parse(layoutField.Value);
    DeviceDefinition deviceDef = layoutDef.GetDevice(device.ID.ToString());

    // Update the rendering's datasource
    RenderingDefinition renderingDefinition =
        deviceDef.GetRendering(renderingReference.RenderingID);
    renderingDefinition.Datasource = newDataSourceValue;
    /* ... unrelated code removed ... */
}

Using RenderingReference.RenderingID in the final statement in that code didn't work, as the RenderingID is the ID of the actual rendering item that lives in /layouts/renderings. So if the item has more than one of the same rendering on a template the code never accesses any renderings after the first instance. I tried using RenderingReference.UniqueID, which appeared to be what I was looking for (the ID of the instance of the rendering):

foreach (RenderingReference renderingReference in parentRenderingReferences)
{
    /* ... unrelated code removed ... */
    var layoutField = new LayoutField(contentItem.Fields[FieldIDs.LayoutField]);
    LayoutDefinition layoutDef = LayoutDefinition.Parse(layoutField.Value);
    DeviceDefinition deviceDef = layoutDef.GetDevice(device.ID.ToString());

    // Update the rendering's datasource
    RenderingDefinition renderingDefinition =
        deviceDef.GetRendering(renderingReference.UniqueID);
    renderingDefinition.Datasource = newDataSourceValue;
    /* ... unrelated code removed ... */
}

In this case, the resulting renderingDefinition object is null, so that doesn't work either.

8

The solution that ended up working for me was to use the DeviceDefinition.GetRenderingByUniqueId method with the RenderingReference.UniqueID object:

foreach (RenderingReference renderingReference in parentRenderingReferences)
{
    /* ... unrelated code removed ... */
    var layoutField = new LayoutField(contentItem.Fields[FieldIDs.LayoutField]);
    LayoutDefinition layoutDef = LayoutDefinition.Parse(layoutField.Value);
    DeviceDefinition deviceDef = layoutDef.GetDevice(device.ID.ToString());

    // Update the rendering's datasource
    RenderingDefinition renderingDefinition =
        deviceDef.GetRenderingByUniqueId(renderingReference.UniqueID);
    renderingDefinition.Datasource = newDataSourceValue;
    /* ... unrelated code removed ... */
}
| improve this answer | |
  • I posted this question and answer together because I spent way too long trying to figure this out myself, and when my team helped me, I didn't want that information to get lost. But please, if you have a better solution, I want to hear it! – Ed Schwehm Oct 20 '16 at 19:33
  • 5
    I would use LayoutField(item) instead of new LayoutField(contentItem.Fields[FieldIDs.LayoutField]) because from Sitecore 8.0 we have Shared Renderings and Final Renderings. Here is the related documentation - doc.sitecore.net/sitecore_experience_platform/content_authoring/… – Tamás Tárnok Oct 20 '16 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.