Enhancing Dynamic Placeholders Code

|
Comments
(0)

Dynamic placeholders have been discussed numerous times throughout the years in Sitecore. It is a very useful feature that can help with numerous problems in a website that has multiple components. However, the current version of the code being passed around in this Stack Overflow Question doesn't well support inserting a component that has another placeholder inside they dynamic placeholder.

In this example, we can call the dynamic placeholder "Frame Content" and the component being inserted into it is a Carousel rendering with a "Carousel Content" placeholder.  

The issues I experienced were:

  1. An inserted component's placeholder's toolbar would take on the same name as the dynamic placeholder's toolbar (so the Carousel's placeholder would appear with the name "Frame Content" as if it was a "Frame Content" inside a "Frame Content").
  2. An inserted component's placeholder's allowed renderings would include both that placeholder's renderings and the dynamic placeholder's renderings (so the Carousel's placeholder would show renderings for both "Frame Content" and "Carousel Content").

What was happening was that the tail of the result of the regex match was being lost. I had to make some changes to get this ability to function correctly.

First, in GetDynamicKeyAllowedRenderings, the modifications commented below had to be made.

            string placeholderKey = args.PlaceholderKey;
            var regex = new Regex(DYNAMIC_KEY_REGEX);
            var match = regex.Match(placeholderKey);
            //check for a tail of the regex to be used later
            var placeholderMatchTail = String.Empty;
            if (match.Success && match.Groups.Count > 0)
            {
                //add tail back
                placeholderMatchTail = args.PlaceholderKey.Replace(match.Groups[0].Value, "");
                placeholderKey = match.Groups[1].Value + placeholderMatchTail;
            }

Later in the same method, only add the dynamic allowed renderings if it has no tail. This fix resolved issue #1. Previously, it would always add the rendering ranges.

                if (placeholderMatchTail == String.Empty)
                    args.PlaceholderRenderings.AddRange(renderings);

Next, in GetDynamicKeyPlaceholderChromeData, a tail needs to be considered for correct chrome data when displaying a placeholder inside a dynamic placeholder. This was just adding back the removed tail, when previously the "newPlaceholderKey" would simply be set to match.Groups[1].Value.

                if (match.Success && match.Groups.Count > 0)
                {
                    var placeholderMatchTail = placeholderKey.Replace(match.Groups[0].Value, "");
                    string newPlaceholderKey = match.Groups[1].Value + placeholderMatchTail;
                    args.CustomData["placeHolderKey"] = newPlaceholderKey;
                    base.Process(args);

After those patches, the dynamic placeholder code being used could function as expected with nested placeholders.

Questions? Comments? Suggestions? Please don't forget to post them below.