A client recently had a need for using multiple instances of a single sub-layout that had Sitecore placeholders on it. They discovered that when they tried implementing this, they ended up with duplicate / replicated data in each placeholder of the sub-layout that was used multiple times. Searching for an answer, we came across this excellent post: Dynamic Placeholder Keys in Sitecore. The only problem is that my client is working on the 6.6 Technical Preview version of Sitecore, and their code is in MVC. The solution provided by that blog post needs some adjusting to work in an MVC environment. This blog post will show you how to do that adjustment so that you are able to create Dynamic Placeholders using Sitecore 6.6 and MVC.
First, some more specific details regarding our problem: I have a Controller Rendering named TwoColumns defined within Sitecore. My corresponding cshtml View has 2 Sitecore placeholders (“Column1”,”Column2”) defined using the OOTB Sitecore HTML helper (IE: @Html.Sitecore().Placeholder(“Column1”)). I then have a page template where I want to reuse my TwoColumns rendering multiple times, as the following picture depicts:
You’ll notice in my picture that I have 3 instances of “TwoColumns” defined, and I am placing a PromotionSpot rendering in each of my “Column1” / “Column2” placeholders contained in my TwoColumns rendering. Without going off on too large a tangent, my PromotionSpot control is set up to render a single line of text above a single image. Thus, the details show that I want 6 total promotions in a 2×3 grid layout. (I am also demoing this on a site that is using an example of the MVC Music Store coupled into Sitecore 6.6.) When I go to my page however, I see the following:
My screenshot is zoomed out, but you should clearly be able to make out 10 full pictures and the top of 2 more – remember, I was going for only 6 total. What happens is that Sitecore is putting each of my specified PromotionSpot renderings in each of the “Column1” / “Column2” placeholders, just like my details tell it to do. Hopefully the above demonstrates the need for a dynamic placeholder – now let’s see how to implement it!
The first thing I need to do is code a class that will have a method to serve as an HTMLHelper for my Dynamic Placeholders. I will also create a method in my class that will allow me to look at the current placeholders on my page and determine if there is already a placeholder with the name of the incoming Dynamic Placeholder on the page. If so, then I will append a “_X” at the end of the placeholder name, where X is an incrementing integer based on the number of times a placeholder exists. The code for my class is the following:
public static class DynamicPlaceholderClass
public static HtmlString DynamicPlaceholder(this SitecoreHelper mySCHelper, string placeholderName)
string DynamicKey = GetDynamicKey(placeholderName);
placeholderName = DynamicKey;
IDisposable disposable = PlaceholderContext.Enter(new PlaceholderContext(placeholderName));
Choosing a Global Software Development Partner to Accelerate Your Digital Strategy
To be successful and outpace the competition, you need a software development partner that excels in exactly the type of digital projects you are now faced with accelerating, and in the most cost effective and optimized way possible.
private static string GetDynamicKey(string placeHolderName)
bool NeedIncrement = false;
int IncrementStep = 0;
var myPlaceholders = ContextService.Get().GetInstances();
foreach (PlaceholderContext myPHContext in myPlaceholders)
if (myPHContext.PlaceholderName == placeHolderName || myPHContext.PlaceholderName.StartsWith(placeHolderName + “_”))
NeedIncrement = true;
placeHolderName += “_” + IncrementStep.ToString();
Now that I have my class, I can switch any of my Sitecore HTML helper Placeholder calls that will be reused on a single page to DynamicPlaceholders. To do this, I open up my TwoColumns.cshtml view and adjust the Placeholder(“ColumnX”) to the following: @Html.Sitecore().DynamicPlaceholder(“Column1”). Note that I also added my namespace (“MVCTestSite.Common”) to the /Views/Web.config file so that Visual Studio intellisense picked up my DynamicPlaceholder HTML helper.
After that, my coding changes are done. If I now refresh my previous page, I see the following:
I now only have 6 images showing, exactly what I was expecting, and so that must be it, right? Not quite – upon closer inspection, while my result is what I’m looking for, the output of my HTML page shows that all of my promotion spots are in my first instance of TwoColumns – the bottom two are completely empty. This is because my DynamicPlaceholder class has set up 6 placeholders with different names – Column1 / Column2 / Column1_1 / Column2_1 / Column1_2 and Column2_2. But my presentation details are still set up to put my PromotionSpot in Column1 / Column2 only. I should now adjust this on my template as follows:
Notice that I’ve adjusted my last 2 sets of PromotionSpots to go into different placeholders. Thanks to my class code, I can be sure that each subsequent DynamicPlaceholder will get a “_X” appended to the end of the name, so I know exactly where to put my renderings. After a publish, my page now looks exactly like I want it to:
So there you have the code to create Dynamic Placeholders using MVC and Sitecore 6.6!