Sitecore 'dynamic placeholders' with MVC

前提是你 提交于 2019-11-29 20:28:20
dunston

I created this extension that creates dynamic placholders

public static class SitecoreHelper
{
    public static HtmlString DynamicPlaceholder(this Sitecore.Mvc.Helpers.SitecoreHelper helper, string dynamicKey)
    {
        var currentRenderingId = RenderingContext.Current.Rendering.UniqueId;
        return helper.Placeholder(string.Format("{0}_{1}", dynamicKey, currentRenderingId));
    }
}

It creates a placeholder with the guid in the name. I also created a step in the pipeline that extracts the guid, and checks for placeholder settings.

Code to get placeholder settings to the dynamic placeholder If you create a dynamic placeholder with @Html.Sitecore().DynamicPlaceholder("test") - the following code takes the setting from the placeholder settings named test

 /// <summary>
/// Handles changing context to the references dynamic "master" renderings settings for inserting the allowed controls for the placeholder and making it editable
/// </summary>
public class GetDynamicKeyAllowedRenderings : GetAllowedRenderings
{
    //text that ends in a GUID
    private const string DYNAMIC_KEY_REGEX = @"(.+)_[\d\w]{8}\-([\d\w]{4}\-){3}[\d\w]{12}";

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

        string placeholderKey = args.PlaceholderKey;
        Regex regex = new Regex(DYNAMIC_KEY_REGEX);
        Match match = regex.Match(placeholderKey);
        if (match.Success && match.Groups.Count > 0)
        {
            placeholderKey = match.Groups[1].Value;
        }
        else
        {
            return;
        }
        // Same as Sitecore.Pipelines.GetPlaceholderRenderings.GetAllowedRenderings but with fake placeholderKey
        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 flag;
            args.HasPlaceholderSettings = true;
            collection = this.GetRenderings(placeholderItem, out flag);
            if (flag)
            {
                args.CustomData["allowedControlsSpecified"] = true;
                args.Options.ShowTree = false;
            }
        }
        if (collection != null)
        {
            if (args.PlaceholderRenderings == null)
            {
                args.PlaceholderRenderings = new List<Item>();
            }
            args.PlaceholderRenderings.AddRange(collection);
        }
    }
}

The following code removes the guid from the chrome data in the pageeditor

/// <summary>
/// Replaces the Displayname of the Placeholder rendering with the dynamic "parent"
/// </summary>
public class GetDynamicPlaceholderChromeData : GetChromeDataProcessor
{
    //text that ends in a GUID
    private const string DYNAMIC_KEY_REGEX = @"(.+)_[\d\w]{8}\-([\d\w]{4}\-){3}[\d\w]{12}";

    public override void Process(GetChromeDataArgs args)
    {
        Assert.ArgumentNotNull(args, "args");
        Assert.IsNotNull(args.ChromeData, "Chrome Data");
        if ("placeholder".Equals(args.ChromeType, StringComparison.OrdinalIgnoreCase))
        {
            string argument = args.CustomData["placeHolderKey"] as string;

            string placeholderKey = argument;
            Regex regex = new Regex(DYNAMIC_KEY_REGEX);
            Match match = regex.Match(placeholderKey);
            if (match.Success && match.Groups.Count > 0)
            {
                // Is a Dynamic Placeholder
                placeholderKey = match.Groups[1].Value;
            }
            else
            {
                return;
            }

            // Handles replacing the displayname of the placeholder area to the master reference
            Item item = null;
            if (args.Item != null)
            {
                string layout = ChromeContext.GetLayout(args.Item);
                item = Sitecore.Client.Page.GetPlaceholderItem(placeholderKey, args.Item.Database, layout);
                if (item != null)
                {
                    args.ChromeData.DisplayName = item.DisplayName;
                }
                if ((item != null) && !string.IsNullOrEmpty(item.Appearance.ShortDescription))
                {
                    args.ChromeData.ExpandedDisplayName = item.Appearance.ShortDescription;
                }
            }
        }
    }
}

Edit

The web.config include settings are included below:

<sitecore>
  <pipelines>

    <getPlaceholderRenderings>
      <processor 
        type="YourNamespace.Pipelines.GetPlaceholderRenderings.GetDynamicKeyAllowedRenderings, YourAssembly"
        patch:before="processor[@type='Sitecore.Pipelines.GetPlaceholderRenderings.GetAllowedRenderings, Sitecore.Kernel']"/>
    </getPlaceholderRenderings>

    <getChromeData>
      <processor
        type="YourNamespace.Pipelines.GetChromeData.GetDynamicPlaceholderChromeData, YourAssembly"
        patch:after="processor[@type='Sitecore.Pipelines.GetChromeData.GetPlaceholderChromeData, Sitecore.Kernel']"/>
    </getChromeData>

  </pipelines>
</sitecore> 

I downloaded the Integrated Dynamic Placeholders package from the sitecore marketplace. When building your page it increments the placeholders with configurable suffix appended to the end of the placeholder key to make them unique, according to their order on the presentation layer. Worked out of the box for me.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!