Skip to content

Instantly share code, notes, and snippets.

@akshaysura
Last active September 4, 2017 16:18
Show Gist options
  • Save akshaysura/fca500bacc71a29e7079c1d55b7955d9 to your computer and use it in GitHub Desktop.
Save akshaysura/fca500bacc71a29e7079c1d55b7955d9 to your computer and use it in GitHub Desktop.
Sitecore Multisite Shared Placeholders and Cascading.
using Sitecore;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Mvc.Extensions;
using Sitecore.Mvc.Pipelines.Response.GetXmlBasedLayoutDefinition;
using Sitecore.Mvc.Presentation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace YOURNAMESPACE.GetXmlBasedLayoutDefinition
{
public class GetFromLayoutFieldWithSharedPlaceholders : GetFromLayoutField
{
private CascadeRenderingsHelper CascadeRenderings;
public override void Process(GetXmlBasedLayoutDefinitionArgs args)
{
var excludedRenderingsPerItem = (Sitecore.Configuration.Factory.CreateObject("excludeRenderingsPerItem", false) as ExcludeRenderings).ExcludedRenderings;
this.CascadeRenderings = Sitecore.Configuration.Factory.CreateObject("cascadeRenderings", false) as CascadeRenderingsHelper;
if (args.Result == null)
{
XElement content = GetFromField(args);
if (content != null)
{
Item item = PageContext.Current.Item;
if (item != null && item.Paths.FullPath != Context.Site.StartPath)
{
Log.Debug("GetFromLayoutField - Process : Not on homepage");
Item homeItem = Context.Database.GetItem(Context.Site.StartPath);
if (homeItem != null && ContinueProcess(item, homeItem))
{
Field homePageLayoutField = homeItem.Fields[FieldIDs.FinalLayoutField];
if (homePageLayoutField != null)
{
string fieldValue = LayoutField.GetFieldValue(homePageLayoutField);
if (!fieldValue.IsWhiteSpaceOrNull())
{
XElement homePageLayout = XDocument.Parse(fieldValue).Root;
XElement dXElement = content.Element("d");
if (dXElement != null && homePageLayout != null)
{
XElement dXElementInHomePageLayout = homePageLayout.Element("d");
if (dXElementInHomePageLayout != null)
{
var layoutElements = dXElementInHomePageLayout.Elements().ToList();
// remove renderings from list of ItemIds
var itemId = item.ID.Guid;
if (excludedRenderingsPerItem != null && excludedRenderingsPerItem.ContainsKey(itemId))
{
List<XElement> layoutElementsToRemove = layoutElements.Where(x => x.Attribute("id") != null && excludedRenderingsPerItem.Values
.Any(y => y.Contains(Guid.Parse(x.Attribute("id").Value))))
.ToList();
layoutElements = layoutElements.Except(layoutElementsToRemove).ToList();
}
foreach (var placeholder in this.CascadeRenderings.Placeholders)
{
dXElement.Add(ExtractContentsFromLayout(layoutElements, placeholder));
}
}
}
}
}
}
}
}
args.Result = content;
}
}
private List<XElement> ExtractContentsFromLayout(IEnumerable<XElement> layoutElements, string placeholder)
{
List<XElement> elements = new List<XElement>();
if (layoutElements.Any())
{
foreach (XElement element in layoutElements)
{
if (element.HasAttributes)
{
if (element.Attribute("ph") != null)
{
string value = element.Attribute("ph").Value.ToLowerInvariant();
if (!string.IsNullOrEmpty(value) && (value.StartsWith("/" + placeholder.ToLowerInvariant()) || value.Equals(placeholder.ToLowerInvariant())))
{
elements.Add(element);
}
}
}
}
}
return elements;
}
private bool ContinueProcess(Item item, Item homeItem)
{
bool returnValue = false;
if (item.TemplateID == homeItem.TemplateID)
return false;
if (this.CascadeRenderings.Dbs.Contains(item.Database.Name))
returnValue = true;
else
return false;
//current item under the home item
if (item.Paths.FullPath.StartsWith(homeItem.Paths.FullPath))
returnValue = true;
else
return false;
if (this.CascadeRenderings.IncludedTemplates.Contains(item.TemplateID))
returnValue = true;
else
return false;
return returnValue;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<mvc.getXmlBasedLayoutDefinition>
<processor type="YOURNAMESPACE.GetXmlBasedLayoutDefinition.GetFromLayoutFieldWithSharedPlaceholders, DLLNAME"
patch:instead="processor[@type='Sitecore.Mvc.Pipelines.Response.GetXmlBasedLayoutDefinition.GetFromLayoutField, Sitecore.Mvc']"/>
</mvc.getXmlBasedLayoutDefinition>
<getPlaceholderRenderings>
<processor type="YOURNAMESPACE.GetPlaceholderRenderings.RemoveSharedRenderings, DLLNAME"
patch:after="processor[@type='Sitecore.Pipelines.GetPlaceholderRenderings.RemoveNonEditableRenderings, Sitecore.Kernel']"/>
</getPlaceholderRenderings>
</pipelines>
<cascadeRenderings type="YOURNAMESPACE.CascadeRenderingsHelper, DLLNAME">
<!-- List of placeholders to cascade. -->
<Placeholders hint="list">
<placeholder>siteheader</placeholder>
<placeholder>sitefooter</placeholder>
</Placeholders>
<!-- List of template ids which this cascading code will process. -->
<IncludedTemplates hint="list:AddIncludedTemplates">
<templateId>{122B3DFC-E993-43FB-8487-BFA4623E23C4}</templateId>
<templateId>{CDE21AC4-57C0-47A4-A431-4229822270DC}</templateId>
<templateId>{3F92D2F9-EC62-4F2B-8423-74E535565A8B}</templateId>
<templateId>{7E54B5C1-AD2A-44F7-83DB-E5DDGDD71F0C}</templateId>
</IncludedTemplates>
<!-- List of db's this code will run on. You can control it per instance. -->
<Dbs hint="list">
<db>master</db>
<db>web</db>
</Dbs>
</cascadeRenderings>
<!-- List of exclusions per page/item. List the page item id and the list of renderings under it to exclude -->
<excludeRenderingsPerItem type="YOURNAMESPACE.ExcludeRenderings, DLLNAME">
<items hint="raw:AddExcludedRendering">
<item itemId="{5C6A1126-8918-44FC-B16C-7F8DSDSD8E1F}">
<renderingId>{033A1329-6B69-4F20-BB6E-D493333D4804}</renderingId>
</item>
<item itemId="{385C76DF-68C5-46E2-9450-79A33333F4A7}">
<renderingId>{25B5FD8D-7E69-4E3B-A29C-F3F3339719DA}</renderingId>
</item>
</items>
</excludeRenderingsPerItem>
</sitecore>
</configuration>
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Pipelines.GetPlaceholderRenderings;
namespace YOURNAMESPACE.GetPlaceholderRenderings
{
public class RemoveSharedRenderings
{
private CascadeRenderingsHelper CascadeRenderings;
public void Process(GetPlaceholderRenderingsArgs args)
{
Assert.IsNotNull(args, "args");
this.CascadeRenderings = Sitecore.Configuration.Factory.CreateObject("cascadeRenderings", false) as CascadeRenderingsHelper;
Item item = Context.Item;
if (item != null && item.Paths.FullPath != Context.Site.StartPath)
{
Item homeItem = Context.Database.GetItem(Context.Site.StartPath);
if (item != null && ContinueProcess(item, homeItem))
{
foreach (var placeholder in this.CascadeRenderings.Placeholders)
{
string value = args.PlaceholderKey;
if (!string.IsNullOrEmpty(value) && (value.StartsWith("/" + placeholder.ToLowerInvariant()) || value.Equals(placeholder.ToLowerInvariant())))
{
args.HasPlaceholderSettings = false;
args.PlaceholderRenderings.Clear();
}
}
}
}
}
private bool ContinueProcess(Item item, Item homeItem)
{
bool returnValue = false;
if (homeItem != null && item != null && item.TemplateID == homeItem.TemplateID)
return false;
if (item != null && this.CascadeRenderings.Dbs.Contains(item.Database.Name))
returnValue = true;
else
return false;
//current item under the home item
if (homeItem != null && item != null && item.Paths.FullPath.StartsWith(homeItem.Paths.FullPath))
returnValue = true;
else
return false;
if (item != null && this.CascadeRenderings.IncludedTemplates.Contains(item.TemplateID))
returnValue = true;
else
return false;
return returnValue;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment