In Sitecore, as well as in all other good CMS’, contents and layouts are separated and there are various ways we can control the rendering of a piece of content. Typically we use Rendering Parameters or Compatible Renderings or a combination of the two. This post will just look into compatible renderings.
When you have two renderings that can render the same piece of content, you edit the Compatible Renderings field of the rendering item. This enables the Replace Rendering button in the Experience Editor (aka Page Editor). It’s worth mentioning that when switching renderings using this technique, the data source etc are being kept.
This adds some maintenance though. If you edit rendering A and say it’s compatible with rendering B, you also have to edit rendering B and say it’s compatible with rendering A. Annoying, right? So let’s solve this.
I’ve created a small piece of code that hooks into the item:saving event and when saving a rendering item, it’ll resolve the compatible renderings and update all the other referenced items accordingly. This is pretty simple but there are a few things to watch out for.
First is always the user experience of course. The compatible renderings field is a sorted list, so the module must retain the sort order on each rendering. Then there are basically two approaches on how we may want this to behave for the content editor. Do we want a complete list of compatible renderings including the currently selected rendering or do we want a list of the other compatible renderings excluding the current selected rendering. There are pros and cons of the two, so I decided to support both.
So the module works like this. If the current rendering is included in the compatible rendering list, the same list will be applied to all the other rendering items, but if it is excluded, all the others will be updated accordingly, having the current item appear at the top. You can think if this as editing the primary rendering and the others are alternative renderings.
Code comments
Looking a bit deeper into the code, the first few statements of the code is pretty standard for every Sitecore event. Remember that the event is fired every time an item is saved, so it is always essential that we exit the event as quickly as possible.
Then there are some edge cases that needs to be taken care of. When removing a compatible rendering, the removed rendering must also be updated. If referenced rendering does not exist or is not a real rendering, these has to be excluded. The Sitecore UI typically prevents duplicates, but I decided to handle that case as well.
When it comes to updating the other rendering items, there are few things to remember. The most important one is that these updates has to be “silent” updates. Otherwise a new item:saving event will occur for every referenced item and we’ll end up in a cascading infinite loop. Then I also realized that I have to do some manual cache clearing of the updated items since the events are not fired.
You can grab the code at github or just grab the package from Sitecore Marketplace
Please let me know what you think about it.