Custom layout resolver

Sitecore provides you the possibility to implement your own layout resolver if the default one is not enough for you. Basically you can change the layout of a page based on a business logic without changing the item in the database.

If you can’t see the code snippets click here to switch to non-AMP mode!

How to do it?

If you are using Sitecore MVC (I hope you are using) you need to inject the following processors in the following pipelines:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<httpRequestBegin>
<processor type="Helix.Skeleton.Feature.CustomLayoutResolver.Processors.CustomLayoutResolver, Helix.Skeleton.Feature.CustomLayoutResolver"
patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.LayoutResolver, Sitecore.Kernel']" resolve="true"/>
</httpRequestBegin>
<mvc.buildPageDefinition>
<processor type="Helix.Skeleton.Feature.CustomLayoutResolver.Processors.CustomProcessXmlBasedLayoutDefinition, Helix.Skeleton.Feature.CustomLayoutResolver"
patch:instead="processor[@type='Sitecore.Mvc.Pipelines.Response.BuildPageDefinition.ProcessXmlBasedLayoutDefinition, Sitecore.Mvc']" resolve="true"/>
</mvc.buildPageDefinition>
</pipelines>
</sitecore>
</configuration>

The first processor is changing the file path of the .cshtml but unfortunately it is not enough.

namespace Helix.Skeleton.Feature.CustomLayoutResolver.Processors
{
using Helix.Skeleton.Feature.CustomLayoutResolver.Constants;
using Sitecore.Data.Items;
using Sitecore.Pipelines.HttpRequest;
public class CustomLayoutResolver : Sitecore.Pipelines.HttpRequest.LayoutResolver
{
public override void Process(HttpRequestArgs args)
{
// CustomLayoutSettings.LayoutItemId is the ID of the new layout item in Sitecore
LayoutItem layoutItem = Sitecore.Context.Database.GetItem(CustomLayoutSettings.LayoutItemId);
Sitecore.Context.Page.FilePath = layoutItem.FilePath;
}
}
}

You also need to change the layout of the context item to point to the new layout item in Sitecore.

namespace Helix.Skeleton.Feature.CustomLayoutResolver.Processors
{
using Helix.Skeleton.Feature.CustomLayoutResolver.Constants;
using Sitecore.Mvc.Pipelines.Response.BuildPageDefinition;
using System.Collections.Generic;
using System.Xml.Linq;
public class CustomProcessXmlBasedLayoutDefinition : Sitecore.Mvc.Pipelines.Response.BuildPageDefinition.ProcessXmlBasedLayoutDefinition
{
protected override IEnumerable<Sitecore.Mvc.Presentation.Rendering> GetRenderings(XElement layoutDefinition, BuildPageDefinitionArgs args)
{
foreach (XElement deviceNode in layoutDefinition.Elements("d"))
{
// change the layout ID to the new layout item ID
deviceNode.SetAttributeValue("l", CustomLayoutSettings.LayoutItemId);
}
return base.GetRenderings(layoutDefinition, args);
}
}
}

After injecting these 2 processors you should able to change the layout of the context item in the current request. The implementation has been tested on Sitecore 8.2 update 7.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s