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.
![Tamás Tárnok = [ C#, Sitecore, … ]](https://trnktms.com/wp-content/uploads/2021/11/pxart_white-small.png)