Uniquely identify your dynamic placeholders in Sitecore 9

Sitecore 9 introduced the dynamic placeholder feature. Please follow the official documentation for more information about when and how to use it.

The problem with the default dynamic placeholders

At first glance, the new dynamic placeholders look very straightforward. Basically, we provide an integer which is the amount of placeholders that should be rendered. Additionally, we can define the seed which indicates the starting value that is used for key generation (see example below). Also the markup customization possibilities are quite nice. However, when I used it in a project I ran into a problem that made me realize that the simple mechanism comes with a huge downside.

Update: jammykam pointed out that the previous example using an accordion component wasn’t beneficial to showcase the problem. Therefore I changed the example to a tab component.

Let’s examine what I mean by that in a simple example. We want to create an tabs component where the Sitecore item structure is as follows:

tabs

This component should give the author the possibility to place other components (e.g. text, image, table) onto each tab content area. This is a classic scenario where dynamic placeholders come into play. If we would use the default dynamic placeholders in this case we might use the following code:

This way, the resulting placeholder keys look something like this:

  • tab-{2845070A-AEBD-4B45-A59D-88269B081204}-0
  • tab-{2845070A-AEBD-4B45-A59D-88269B081204}-1
  • tab-{2845070A-AEBD-4B45-A59D-88269B081204}-2

Each placeholder receives a unique key which is used to map renderings to it. However, we do not know which placeholder corresponds to which tab item. Here is why this is problematic: Let’s assume an author is not happy with the sequence of the tab items and puts „Events“ before „News“. What happens now is that all renderings which have been assigned to „News“ are getting rendered in „Events“ and vice versa. Honestly, I couldn’t come up with an elegant solution for this problem. If you found one, then I would be glad if you could give me a hint!

The solution

The solution I came up with is quite simple but involves extending the default functionality of dynamic placeholders. Basically, we need to add a unique identifier to each placeholder. Therefore I created a new helper method which lets us do that. This method takes in the placeholder name and a Sitecore.Data.ID object as parameters. The example mentioned before looks like this with the extended version:

This way the resulting placeholder keys look like this:

  • tab-{2845070A-AEBD-4B45-A59D-88269B081204}-{EE1CC84B-EB2D-4250-A3DE-F4DF0DB82138}
  • tab-{2845070A-AEBD-4B45-A59D-88269B081204}-{C6B08567-16ED-428E-9014-DD516B294E5B}
  • tab-{2845070A-AEBD-4B45-A59D-88269B081204}-{9487CD58-8CBB-423F-81D8-3E8612490D40}

SitecoreHelper extension

As mentioned before, I added a new extension method for the SitecoreHelper type.

Dynamic Placeholder pipeline customization

If you already followed the link to the official documentation of dynamic placeholders then you might have seen that Sitecore 9 offers pipelines to extend the basic dynamic placeholders. The following configuration and corresponding pipeline processors enable the recognition of a unique identifier in the placeholder key. The processors are built to work side-by-side with the existing features as for Sitecore 9.0 Update-1. As you might have noticed, I needed to replace the RemovePlaceholderUniqueKeySuffix processor so this statement might not be true in the future. Unfortunately, I couldn’t figure out a way to avoid replacing a processor.

5 Gedanken zu “Uniquely identify your dynamic placeholders in Sitecore 9

  1. The problem you have is that you add the Accordian Items *not* dynamically, and then you want to bind the contents of the item dynamically… you should just do everything dynamically.

    Instead of relying on items/folders being added in the Content Editor, have a general „Accordian“ Rendering with placeholder, into which you add an Accordian Item which has a datasource to the folder item. Inside that you item you add the content as normal.

    The accordian item can be fully managed from Experience Editor, personalized, re-ordered etc without leaving EE mode.

    • Hi jammykam 🙂

      Thank you for your response. It makes totally sense. I have to admit that the accordion example I’ve used in this article is not accurate to display the problem. In fact we mainly ran into problems where we needed to have markup outside of the dynamic placeholder that corresponds to the added elements. This happens for example in a tab component where the user can click a tab and in response another content gets displayed. Here is an example code:

      <div class="tab-component">
          <ul>
              <!-- The <li> elements need to correspond to the dynamically added content elements -->
          </ul>
          <div>
              <!-- Here is a dynamic placeholder -->
          </div>
      </div>

      There are ways to make this work, such as using java script to render the ul/list-list or using another dynamic placeholder in the place of the ul/li-list. However, they don’t feel straight forward. If you don’t mind, I would be glad if you could share your preferred approach for this kind of situation.

      Cheers, Fabian

  2. Hi Fabian,

    I have the exact same problem. I had one idea to solve this, and I know this feels like a complete hack, but it might work in practice.

    The idea is to take the GUID of the Tab ItemID and strip out all the letters, leaving only numbers, and then using that as the integer seed value.

    I fully recognize this does not guarantee a unique seed value, but what is really the likelihood of a colliding seed value in this case?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>