4
votes

I'm implementing Dynamic Placeholders in Sitecore 7 as described in the articles

It is working correctly such that I can add the same Rendering to the layout and the renderings will go in the appropriate Dynamic Placeholder. However when I click to add a Rendering to the Dynamic Placeholder, the placeholder settings aren't being used.

What I am expecting is to be prompted with the allowed renderings that may be placed on the Dynamic Placeholder. Instead the Rendering/Layout tree is presented to manually select the rendering - giving Content Editors the ability to add disallowed renderings to the placeholder.

I have debugged the code and the correct Placeholder Settings Item is being found for the Dynamic Placeholder and the list of allowed Renderings are being retrieved however despite being set in the args the list is not presented for the User. See code below.

public class GetDynamicKeyAllowedRenderings : GetAllowedRenderings
{
    //string that ends in a GUID
    public const string DynamicKeyRegex = @"(.+){[\d\w]{8}\-([\d\w]{4}\-){3}[\d\w]{12}}";

    public new void Process(GetPlaceholderRenderingsArgs args)
    {
        Assert.IsNotNull(args, "args");

        // get the placeholder key
        string placeholderKey = args.PlaceholderKey;
        var regex = new Regex(DynamicKeyRegex);
        Match match = regex.Match(placeholderKey);

        // if the placeholder key text followed by a Guid
        if (match.Success && match.Groups.Count > 0)
        {
            // Is a dynamic placeholder
            placeholderKey = match.Groups[1].Value;
        }
        else
        {
            return;
        }

        Item placeholderItem = null;
        if (ID.IsNullOrEmpty(args.DeviceId))
        {
            placeholderItem = Client.Page.GetPlaceholderItem(placeholderKey, args.ContentDatabase,
                                                             args.LayoutDefinition);
        }
        else
        {
            using (new DeviceSwitcher(args.DeviceId, args.ContentDatabase))
            {
                placeholderItem = Client.Page.GetPlaceholderItem(placeholderKey, args.ContentDatabase,
                                                                 args.LayoutDefinition);
            }
        }

        // Retrieve the allowed renderings for the Placeholder
        List<Item> collection = null;
        if (placeholderItem != null)
        {
            bool allowedControlsSpecified;
            args.HasPlaceholderSettings = true;
            collection = this.GetRenderings(placeholderItem, out allowedControlsSpecified);
            if (allowedControlsSpecified)
            {
                args.CustomData["allowedControlsSpecified"] = true;
            }
        }
        if (collection != null)
        {
            if (args.PlaceholderRenderings == null)
            {
                args.PlaceholderRenderings = new List<Item>();
            }
            args.PlaceholderRenderings.AddRange(collection);
        }
    }
}

As this code was developed for Sitecore 6.5 / 6.6 I wonder if in the jump to Sitecore 7.0 brought a change that affects the latter half of the code

1

1 Answers

6
votes

I have found the source of the issue by decompiling the Sitecore 7 Kernel and viewing the default GetAllowedRenderings class. If Allowed Renderings are found the ShowTree Option needs to be set to false. See below

public class GetDynamicKeyAllowedRenderings : GetAllowedRenderings
    {
        //string that ends in a GUID
        public const string DynamicKeyRegex = @"(.+){[\d\w]{8}\-([\d\w]{4}\-){3}[\d\w]{12}}";

        public new void Process(GetPlaceholderRenderingsArgs args)
        {
            Assert.IsNotNull(args, "args");

            // get the placeholder key
            string placeholderKey = args.PlaceholderKey;
            var regex = new Regex(DynamicKeyRegex);
            Match match = regex.Match(placeholderKey);

            // if the placeholder key text followed by a Guid
            if (match.Success && match.Groups.Count > 0)
            {
                // Is a dynamic placeholder
                placeholderKey = match.Groups[1].Value;
            }
            else
            {
                return;
            }

            // Same as Sitecore.Pipelines.GetPlaceholderRenderings.GetAllowedRenderings from here but with fake placeholderKey
            // i.e. the placeholder without the Guid
            Item placeholderItem = null;
            if (ID.IsNullOrEmpty(args.DeviceId))
            {
                placeholderItem = Client.Page.GetPlaceholderItem(placeholderKey, args.ContentDatabase,
                                                                 args.LayoutDefinition);
            }
            else
            {
                using (new DeviceSwitcher(args.DeviceId, args.ContentDatabase))
                {
                    placeholderItem = Client.Page.GetPlaceholderItem(placeholderKey, args.ContentDatabase,
                                                                     args.LayoutDefinition);
                }
            }

            List<Item> collection = null;
            if (placeholderItem != null)
            {
                bool allowedControlsSpecified;
                args.HasPlaceholderSettings = true;
                collection = this.GetRenderings(placeholderItem, out allowedControlsSpecified);
                if (allowedControlsSpecified)
                {
                    // Hide the Layout/Rendering tree to show the Allowed Renderings
                    args.Options.ShowTree = false;
                }
            }
            if (collection != null)
            {
                if (args.PlaceholderRenderings == null)
                {
                    args.PlaceholderRenderings = new List<Item>();
                }
                args.PlaceholderRenderings.AddRange(collection);
            }
        }
    }

This is a change brought in by Sitecore 7 it seems.