Follow up on: Hacking the layout rendering

In my previous post I wrote about fetching the layout definitions of sub pages and add them to a top page and making Sitecore think they belong to the top page. This was done on Sitecore.NET 6.5.0 (rev. 111123).

This week we tried implementing the same function on a Sitecore 6.6.0 (rev. 130404). While the base function worked, with it displaying the sub pages layouts on the top page, the DMS didn’t handle if there were any conditional renderings. After some looking around in the pipelines I found out that the evaluations of the conditions were done in the insertRenderings pipeline which in turn was run before the renderLayout pipeline where my pipeline to fetch the layout definitions were. So I was adding the layout definitions after Sitecore had evaluated the conditions.

<insertRenderings>
        <processor type="Sitecore.Pipelines.InsertRenderings.Processors.GetItem, Sitecore.Kernel"/>
        <processor type="Sitecore.Pipelines.InsertRenderings.Processors.AddPageDesignerRenderings, Sitecore.Kernel, Version=6, Culture=neutral"/>
        <processor type="Sitecore.Pipelines.InsertRenderings.Processors.AddRenderings, Sitecore.Kernel"/>        
        <processor type="Sitecore.Pipelines.InsertRenderings.Processors.EvaluateConditions, Sitecore.Kernel"/>
</insertRenderings>

The insertRenderings pipeline

To solve this problem I had to add the layout definitions before the conditions were evaluated which was done in the EvaluateConditions processor. What we did was to create a pipeline which basically did the same as before and add it just after the AddRenderings processor, looking like this.

public class AddSubPageRenderings : InsertRenderingsProcessor
{
    public override void Process(InsertRenderingsArgs args)
    {
        Assert.ArgumentNotNull((object)args, "args");
        if (args.ContextItem == null)
            return;
        DeviceItem device = Context.Device;
        if (device == null)return;
        if (!args.ContextItem.TemplateID.Equals(new ID("{D42E1DBF-D9F5-4DC8-A8B7-0F8B5BC5758C}"))) return;
        if (!Sitecore.Context.PageMode.IsNormal) return;
        var referenses = new List();
        foreach (var child in args.ContextItem.Children.Where(i => i.IsPublished()))
        {
            var renderings = child.Visualization.GetRenderings(device, true);
            foreach (var renderingReference in renderings)
            {
                if (!renderingReference.Placeholder.Equals("content", StringComparison.InvariantCultureIgnoreCase) && !renderingReference.Placeholder.StartsWith("/main/content", StringComparison.InvariantCultureIgnoreCase)) continue;
                renderingReference.Settings.DataSource = string.IsNullOrEmpty(renderingReference.Settings.DataSource) ? child.Paths.FullPath : renderingReference.Settings.DataSource;
                referenses.Add(renderingReference);
            }
         }
        args.Renderings.AddRange(referenses);
        args.HasRenderings = args.Renderings.Count > 0;
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <insertRenderings>
        <processor patch:after="*[@type='Sitecore.Pipelines.InsertRenderings.Processors.AddRenderings, Sitecore.Kernel']" type="Test.Pipelines.AddSubPageRenderings, Test"/>
      </insertRenderings>
    </pipelines>    
  </sitecore>
</configuration>

Now all the conditional renderings from the sub pages are evaluated accordingly.