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.

1 Answer 1

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 ... */
}
2
  • 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, 2016 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/… Oct 20, 2016 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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