True Dynamic Placeholders in MVC – Part 2

After my previous post while working with Sitecore I realized there was an issue with the implementation.  Although it works great in the Device Editor (PLD) within the Content Editor, this implementation does not work with the Experience Editor.  So I had to go back to the drawing board and come up with a solution that works for the Content Editor and the Experience Editor.  This blog post will discuss the changes I made to the Presentation Pipelines which specifically involve the Experience Editor to make this work.  If you want a solution that only works for the Content Editor, you can read my first post here: True Dynamic Placeholders with MVC.  However like most I’m sure you’ll need a solution that works well with both, so continue reading.

So the root cause to why this change did not work with the experience editor, is because it doesn’t know how to handle our Dynamic Placeholder Key’s which are being generated by our Html Helper extension method that we created, that you use within the View using this statement:  @Html.Sitecore().DynamicPlaceholder(“Name”)

The first change you’ll need to make is to setup the pipeline that will handle getting placeholder settings by the Placeholder Key.  By default without this change, you will not be able to add any components to the page (unless you update your Sitecore.ExperienceEditor.config file to allow you to place components when a Placeholder Setting isn’t specified.).  With this change, it will set the placeholder key to match the placeholder names that you are using.  For example, you might have a placeholder name for the main area of the page called “Main”.  The extension method @Html.Sitecore().DynamicPlaceholder(“Main”), would generate this as Main|{UniqueRenderingIDGuid}.  This code will remove the |{UniqueRenderingIDGuid} from the placeholder key, so you will get back global and template level placeholder settings that are mapped to “Main” placeholder key.

Once that change is done, you’ll need to update the Default Chrome Placeholder Data, so that the Chrome Display Name and in some situations ExpandedDisplayName, match the Placeholder name you’ve used in the View, so for example, it would display “Main” instead of “Main|{UniqueRenderingIDGuid}.  You don’t necessarily need to make this change, but will make the experience a little more intuitive and friendly for the content editor.

The last part and probably the most important step is the code for the InsertRendering.cs which is run when you “Add a Component” to the page via the Experience Editor.  Like the other code from the previous snippets, it will strip off the |{UniqueRenderingIDGuid} from the Placeholder Key, as well as ensure that the key only contains the last element.  From there it will try to insert the rendering that you are adding.  The existing code would rely on a Position that is set within the Javascript on the front end.  I go with a different approach, because the placeholder key contains information about the Unique ID of the rendering.  I can use that information to insert the new rendering immediately following that rendering that matches this unique id.

Finally the last step of course is to configure your pipelines in a patch file.  Which I show how to do so below.  This patch file includes the existing rendering for the “PerformRendering” that you added in my previous article.

Well that’s it, but I’m still working through and ensuring all scenarios are handled when using the Experience Editor, so there could be a third part to this article eventually.  If anyone implements this and finds issues with anything, please let me know so I can address this.  I’ve also setup a Github Repository with all the source from this series on Github.

Keep in mind this implementation only works with MVC.  I will work on an implementation for Web Forms soon.  Also this has only been tested with Sitecore 8.1, but I will start testing with earlier versions of Sitecore soon.

  • RogrH

    Hi, it doesn’t actually compile, IInsertRenderingArgs doesn’t exist.

    • Dylan Young

      Hi, this is a mistake on my part. Make sure you include a reference to Sitecore.ExperienceEditor, that should fix this build error.

    • Dylan Young

      Actually Mvc wasn’t added either. I’ll update these in the github repo later today. Just keep in mind if you see further build errors it’s related to Site.Infrastructure not having a reference to 5.2.3 of Mvc. Also in Site.Web, I needed to update the reference to 5.2.3 from 5.2.2.