Hey Sitecorians,
Hope you’re doing well with Sitecore.
Many a time we need an option to have some utility that will do the job easily and save the time for the content team to get things done faster and take the bunch out of the plate. One such requirement was for adding the sub-layout/rendering in bulk. I quickly built a utility that will do the job easier for the content team.
A simple utility that will do the following:
- Add Rendering
- Assign placeholder key to a newly added rendering
- Add appropriate data-source value
The utility will ask for the following:
- Parent-item ID
- Template ID – Which items, defined from the given template need to have the rendering.
- Rendering ID
- Data-Source Value
- Placeholder Key
if (parent != null) { // Default device from Sitecore var deviceItem = db.GetItem("{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}"); DeviceItem device = new DeviceItem(deviceItem); // Iterate through all the child items. foreach (Item childItem in parent.Axes.GetDescendants()) { // Check if the item do have any other renderings. if (childItem.Fields != null && childItem.Fields["__Renderings"] != null && childItem.Fields["__Renderings"].ToString() != string.Empty) { // Check if item do have the given rendering already assigned. var renderings = item.Visualization.GetRenderings(device, true).Where(r => r.RenderingID == Sitecore.Data.ID.Parse(txtRenderingID.Text)).ToArray(); if (renderings.Count() > 0) { Sitecore.Diagnostics.Log.Info("Item not updated: " + item.Paths.Path + ", Message: Rendering already Exist. ID " + txtRenderingID.Text, this); renderingAlreadyExist = true; } // Get the layout definitions and the device Sitecore.Data.Fields.LayoutField layoutField = new Sitecore.Data.Fields.LayoutField(item.Fields[Sitecore.FieldIDs.LayoutField]); if (!string.IsNullOrEmpty(layoutField.Value)) { Sitecore.Layouts.LayoutDefinition layoutDefinition = Sitecore.Layouts.LayoutDefinition.Parse(layoutField.Value); Sitecore.Layouts.DeviceDefinition deviceDefinition = layoutDefinition.GetDevice(device.ID.ToString()); if (deviceDefinition.Renderings != null && deviceDefinition.Renderings.Count > 0) { var renderingID = txtRenderingID.Text; // If rendering already exist - Update Data-Source and Placeholder Key if (renderingAlreadyExist) { var renderingItem = deviceDefinition.GetRendering(renderingID); if (renderingItem != null) { // Update the renderings datasource value accordingly renderingItem.Datasource = txtNewDataSourceID.Text; renderingItem.Placeholder = txtPlaceholderKey.Text; sb.Append("Item updated: " + item.Paths.Path).Append(", Rendering updated.").Append("<br />"); } } else { // Get the Rendering and set required properties. RenderingDefinition def = new RenderingDefinition(); def.ItemID = renderingID; def.Datasource = txtNewDataSourceID.Text; def.Placeholder = txtPlaceholderKey.Text; deviceDefinition.AddRendering(def); sb.Append("Item updated: " + item.Paths.Path).Append(", Rendering Added.").Append("<br />"); } // Save the layout changes item.Editing.BeginEdit(); layoutField.Value = layoutDefinition.ToXml(); item.Editing.EndEdit(); } } } } }
Let me quickly go-through with what I did in above code.
- Get the default device.
- Iterate through all the child items
- Check If the item does have any other rendering — If not then continue with the next item
- Check If Item does have the given rendering already assigned
- Get the layout definition
- Get the device definition — This is based on the default device. Default device ID is same for all the Sitecore Versions.
- If rendering already exist – Get the rendering and update Data-Source Value and Placeholder Key otherwise Add the new rendering into Device Definition
- Save the changes.
There are many things not done in this as I was sure this will do the job and carefully executed by the right person. If you are planning to give it to someone who can enter anything in the text-box then you need to have the proper error-handling, null check, and Template/Item ID check.
aspx file — Download
Happy Sitecoring!