Fetch Site Settings in Layout Service using GetLayoutServiceContext Pipeline

We can add our own data to the context object at any time by extending the getLayoutServiceContextpipeline provided by the Layout Service.


In my previous blog, I discussed about GraphQL approach to fetch the Site Settings item which is absolutely required in many cases where Site specific settings needs to be available across the renderings.

As we already know in Sitecore headless architecture these settings item won't be exposed to Layout service by default since this is not a part of any renderings but many renderings depend on these settings value.

So we have the LayoutServiceContextpipeline provided by the Layout Service to accomplish this task.

Let's do it using GetLayoutServiceContext pipeline. 

Assumption - Visual Studio Solution setup is already done based on the project needs or using getting started template.

Use case - Let's consider this site structure and suppose we have to fetch the highlighted Site Settings using GetLayoutServiceContext pipeline.

  • Open your Visual Studio Solution.
  • Create one Class in your solution let's say - CustomSitecoreContextExtension 
  • Import the following name spaces - 

using System;
using System.Linq;
using System.Collections.Generic;
using Sitecore.LayoutService.Serialization.ItemSerializers;
using Sitecore.JavaScriptServices.Configuration;
using Sitecore.JavaScriptServices.ViewEngine.LayoutService.Pipelines.GetLayoutServiceContext;
using Sitecore.LayoutService.ItemRendering.Pipelines.GetLayoutServiceContext;
using Newtonsoft.Json.Linq;
using Sitecore.Data.Items;

  • Inherit JssGetLayoutServiceContextProcessor to your CustomSitecoreContextExtension class.
  • Override the DoProcess method.
protected override void DoProcess(GetLayoutServiceContextArgs args, AppConfiguration application)
        {
            try
            {
                Assert.ArgumentNotNull((object)args, nameof(args));
                var renderedItem = args?.RenderedItem;
                if (renderedItem == null)
                {
                    _logger.Info("RenderedItem is null, in CustomSitecoreContextExtension", this);
                    return;
                }
                //Get the root item and its child items, based on renderedItem
                var rootItem = renderedItem?.Axes?.GetAncestors()?.Where(x => x.TemplateID.ToString() == Constants.Templates.TemplateID).FirstOrDefault();
                var contextSettingsFolder = rootItem?.Children?.FirstOrDefault(x => x.TemplateID.ToString() == Constants.Templates.ContextSettingsID);
                if (rootItem == null || contextSettingsFolder == null)
                {
                    _logger.Info("RootItem or contextSettingsFolder  is not available, in CustomSitecoreContextResolver", this);
                    return;
                }
                _logger.Info(" RootItem ID : "+ rootItem.ID + " and ContextSettingsFolderItem ID: " + contextSettingsFolder.ID, this);
                IEnumerable items = contextSettingsFolder?.GetChildren();
                List itemList = items != null ? items.ToList() : null;
               
                //Define the context keys for all items and the order is important
                string[] contextDataNames = { Constants.TextStrings.SiteSettings, Constants.TextStrings.DisclaimerPopup, Constants.TextStrings.CallCenter };
                int i = 0;
                if (itemList != null)
                {
                    foreach (Item childitem in itemList)
                    {
                        IItemSerializer itemSerializer = args?.RenderingConfiguration?.ItemSerializer;
                        var childItemJSON = itemSerializer?.Serialize(childitem);
                        if (childItemJSON == null)
                            return;                        
                        args.ContextData.Add(contextDataNames[i], JObject.Parse(childItemJSON));
                        i++;
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Error("Error in CustomSitecoreContextExtension pipeline method", ex, this);
            }
        }
  • Declare the following constants in your static class or create new to hold these constants. 
public const string TemplateID = "{061CBA15-5474-4B91-8A06-17903B102B82}"; //This is Settings template ID.
public const string ContextSettingsID = "{28F7313D-A1BD-4BC4-88B0-8322DEDAB0EF}"; // This is the specific settings item ID.
public const string SiteSettings = "siteSettings"; //This is your chosen Name for Settings item which will appear in Layout Service context data.
  • Now, patch your processor in the config file. Type name could be different as per your project.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
    <pipelines>
	<group groupName="layoutService">
	    <pipelines>
		<getLayoutServiceContext>
		    <processor type="MyProject.Foundation.JssExtension.Pipelines.Resolvers.CustomSitecoreContextExtension, MyProject.Foundation.JssExtension" resolve="true"> </processor>                      
		</getLayoutServiceContext>
            </pipelines>
	</group>
    </pipelines>
</sitecore>
</configuration>
This is it. Now publish your code and refresh Layout Service url. You should see the Site Settings item in the Context data section.

Comments

Popular posts from this blog

Setup Sitecore XM Cloud Dev Environment using Docker

Sitecore Content Hub - Triggers, Actions and Scripts

All Blog Posts - 2023