I’m still working on the third post about configuration, I have to admit that I’ve lost a bit of drive on it. So I thought I’d change gears a little and share some information I found around rendering parameters and personalisation. For anyone who doesn’t know what rendering parameters are, I’d suggest this article by Vasiliy Fomichev, which explains them nicely.
We use rendering parameters a fair bit at Codehouse in order to allow editors to control the more presentation-oriented settings without editors needing to duplicate or clone their datasource items. For example, a call-to-action on one page might have the same content on two pages, but need a different background colour in order to fit the rest of the page. Developers often forget that the DRY principle can be applied to content too: give the editors the tools so that they don’t have to duplicate content where they don’t need to.
Recently, though, I came across a specific situation where they seemed to be a little broken.
I was working on a project that had rendering parameters set up for various things, and one of the content editors raised a ticket. They said that one of the renderings was showing up “missing some styling” when it was swapped in with personalisation. So I picked the ticket up and had a look at what was going on. It has been known for a while that Sitecore doesn’t allow you to personalise rendering parameters out-of-the-box, so I had a hunch that this was the cause.
The problem occurs when you have two renderings (A and B), which have rendering parameters (X and Y). When rendering A is on the page with parameters X, and a personalisation rule is applied to swap rendering A with rendering B, you don’t get the chance to specify the parameters Y – there’s simply no way in the UI to do it. When the personalisation rule executes, B is shown instead of A as expected. However, Sitecore also passes parameters X into rendering B rather than the defaults for parameters Y. Great. Thanks.
In this case, the fields on the two rendering parameters templates were almost completely different, which is why the rendering appeared so broken to the content editor who reported the issue.
I had elected to stop hard-coding fall-back values into the renderings for the most part, because using standard values on the rendering parameters template does the job; and because it gave a single, central place to manage these default values that did not need a release to change. I was not particularly looking forward to reversing that and having to go through all the renderings to locate the ones using rendering parameters and hard-code some default values, so I had a little dig around to see if there was another option.
Fortunately, there is, and it’s actually quite easy to do (once you know how). More interestingly, with some (likely significant) UI work, it might be possible to adopt this in order to allow proper use of personalisation with rendering parameters. I didn’t look too deeply into that, maybe I’ll pick it up in the future if someone else doesn’t before then.
The changes to the rendering object are all applied by a single pipeline processor, PersonaliseAndResetParameters, whose methods are – thankfully – marked as virtual. It was a simple matter to override the ApplyChanges method. The thing that took the longest was figuring out how to get Sitecore to hand over the default rendering parameter values that it clearly knew, which for the amount of digging involved turned out to be disappointingly simple.
The end result was the following:
It is worth noting that the above logic does nothing more than ensure that switched out renderings always receive the default rendering parameters. Someone seeking to use this may want to consider amending the above logic to only add parameters that are missing, if that would be more desirable. In my case, this was not necessary, but others’ needs may differ. This code also will only work with MVC, it’s possible that it may be adapted to work with WebForms also.
Lastly, it is possible that more knowledgeable content editors may already have worked around this by manually crafting the parameters on the main rendering so that they also include parameters needed with the one being inserted. Care should be taken in this case, as this pipeline will take precedence over such efforts.