Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sitecore 'dynamic placeholders' with MVC

Tags:

I'm looking for a working Dynamic Placeholder solution in MVC. There are at least two good descriptions of this "pattern" for use with WebForms:

  • http://trueclarity.wordpress.com/2012/06/19/dynamic-placeholder-keys-in-sitecore/
  • http://www.techphoria414.com/Blog/2011/August/Dynamic_Placeholder_Keys_Prototype

And I also found this blog explaining how to do it with MVC:

  • http://blogs.perficient.com/portals/2012/10/17/sitecore-mvc-dynamic-placeholders/

First I have tried to implement Techphoria's method (with GUIDs) using techniques from the MVC blogpost (extension of the SitecoreHelper) and I also tried implementing the last described method (uses number suffixes that are incremented Column_1, Column_2, etc).

With all the variations I tried I didn't succeed in creating a working solution. My placeholders don't get properly named (I ended up with strange placeholder structures, or placeholders repeating themselves).

Without going into the specifics of my attempts, I would like to know if anyone else has a working solution ready that I could use.

If I can't find an already working solution, I will describe my problem in more detail and see if I can get that to work.

like image 332
Ruud van Falier Avatar asked Feb 28 '13 11:02

Ruud van Falier


People also ask

What is the use of dynamic placeholder in Sitecore?

When you use dynamic placeholders, you can add the same placeholder name several times. You can do this across multiple renderings, and you can even use the same placeholder multiple times in a single rendering.

What is placeholder settings in Sitecore?

Placeholders in Sitecore allow the dynamic assembly of page layouts either by allowing the editors to design specific pages, or by allowing administrators to create predefined variations of layouts on Page Type templates (see Template types).

What is a rendering in Sitecore?

Renderings are used to render a page or a part of a page in Sitecore. There are many renderings in sitecore and one among them is the view rendering. View rendering is used in components which involve little logic without any database transaction or a MVC controller. It is used to render a .


1 Answers

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>  
like image 169
dunston Avatar answered Sep 20 '22 04:09

dunston