Monday, March 11, 2019

Hiding default SXA rendering styles in cloned SXA renderings

For our project, we clone existing SXA renderings and customize to the designs. While doing so what I noticed is that certain default styles show up along with the custom styles created as per the design.

The client didn't like the idea of the unwanted styles showing up so had to hide that and show only the custom ones which can be used. Below snapshot shows the styles that needs hiding.


On investigating further I found that the styles to be shown on the control properties dialog is based on the Allowed Renderings field in the style template. If there is nothing selected in the Allowed renderings for a style it would show up on all the renderings properties.

So to achieve what we wanted I had below two options:

  1. List all the OOTB SXA components in Allowed renderings for the styles that show for all the components.  This to me is not an elegant solution
  2. Add a custom field for Disallowed renderings and write a custom pipeline to use the new field. 
I went with option 2. 

First thing I had to do is to figure out the pipeline responsible for showing the styles in the control properties. From the showconfig, I figured that below pipeline processors are 


<getStyles patch:source="Sitecore.XA.Foundation.Presentation.config">
<processor type="Sitecore.XA.Foundation.Presentation.Pipelines.GetStyles.GetSiteStyles, Sitecore.XA.Foundation.Presentation" resolve="true"/>
<processor type="Sitecore.XA.Foundation.Presentation.Pipelines.GetStyles.GetSharedStyles, Sitecore.XA.Foundation.Presentation" resolve="true"/>
</getStyles>

So I had to override the GetSiteStyles processor for our purpose. Below is the config patch file I created to patch the GetSiteStyles processor.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <getStyles>
        <processor type="xxxxx.Common.Pipeline.GetSiteStyles,xxxxx.Common" 
                   patch:instead="*[@type='Sitecore.XA.Foundation.Presentation.Pipelines.GetStyles.GetSiteStyles, Sitecore.XA.Foundation.Presentation']" 
                    resolve="true" />
      </getStyles>
    </pipelines>
  </sitecore>
</configuration>

Introduced a new field called "Disallowed Renderings", which is a duplicate of Allowed Renderings field, to /sitecore/templates/Foundation/Experience Accelerator/Presentation/Style template 

Then I copied over the code for GetSiteStyles to my solution using dotPeek and modified it to handle the new field to not show the styles for renderings which are selected in Disallowed renderings. 

Below is the code for the custom processor.

using Sitecore.Data;
using Sitecore.Data.Items;
using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore.XA.Foundation.Presentation;
using Sitecore.XA.Foundation.Presentation.Pipelines.GetStyles;

namespace xxxxx.Common.Pipeline
{
    public class GetSiteStyles : GetStylesProcessorBase
    {
        private readonly IPresentationContext _presentationContext;

        public GetSiteStyles(IPresentationContext presentationContext)
        {
            this._presentationContext = presentationContext;
        }

        public void Process(GetStylesArgs args)
        {
            if (string.IsNullOrEmpty(args.Rendering))
                return;
            ItemUri renderingItemUri = new ItemUri(args.Rendering);
            Item stylesItem = this._presentationContext.GetStylesItem(args.ContextItem);
            if (stylesItem == null)
                return;
            args.Styles = (IList<Item>)args.Styles.Concat<Item>(((IEnumerable<Item>)stylesItem.Axes.GetDescendants()).Where<Item>((Func<Item, bool>)(i =>
            {
                if (this.IsStyleItem(i))
                {
                    if(!IsDisAllowed(i, renderingItemUri))
                    {
                        return this.IsAllowed(i, renderingItemUri);
                    }
                }
                return false;
            }))).ToList<Item>();
        }

        public static ID DisAllowedControls { get; } = new ID("{C118A21A-6E60-4AAA-93F4-0A64FDA344E2}");

        protected virtual bool IsDisAllowed(Item styleItem, ItemUri renderingItemUri)
        {
            string str = styleItem[DisAllowedControls];
            if (str != "")
                return str.Contains(renderingItemUri.ItemID.ToString());
            return false;
        }
    }
}

After doing the above stuff I could select my custom rendering in the Disallowed renderings field for the Style that showed up by default like shown in the picture below:



After this below is how the control properties showed with only the custom styles. 

Problem Solved! 





No comments:

Post a Comment