How to Implement Custom Rendering Resolver for extending the Layout service in Sitecore JSS


Although Sitecore JSS allows you to configure a Rendering Contents Resolver on each rendering, which determines how a rendering and its associated data are serialized. Rendering Contents Resolvers are configured in /sitecore/system/Modules/Layout Service/Rendering Contents Resolverswe might sometimes need some custom data in Layout service which is more relevant to the need of product. so in that case we have to write our custom Rendering Resolver in Sitecore , here we will discuss about that.  

By default, Sitecore JSS provides below listed resolver :

  1. Datasource Resolver - The default behavior, serializes the rendering's datasource item
  2. Datasource Item Children Resolver - Serializes the children of the datasource item
  3. Context Item Resolver - Serializes the context item instead of the datasource item
  4. Context Item Children Resolver - Serializes the children of the context item
  5. Folder Filter Resolver - Serializes the descendants of the datasource item, excluding folders.
By default Sitecore provides three ways to Extend the Layout service.

  1. Use JSS GraphQL Support
  2. Choose or configure a builtin Rendering Contents Resolver(one out of above mentioned rendering resolvers)
  3. Create an RenderingContentsResolver

In this blog we will learn how to Create Rendering Contents resolver by following below listed steps:

 Step 1: Create a Content Resolver Item in Sitecore Under the Rendering Contents Resolvers folder.

Below is the screenshot for Sitecore inbuilt Resolver(Context Item Childere Resolver)


We have to create the Content Resolver item and bind it to the class and the assembly name. We leave use "context item" unchecked because we want to use our datasource and even extend the template.

Below is screenshot for custom Content Resolver Item



Step 2: Now we need to create the custom code. No extra configuration in Sitecore is needed to be able to use this code. So its sufficient when the assembly resides in the bin-folder.

using Newtonsoft.Json.Linq;
using Sitecore.Data.Items;
using Sitecore.LayoutService.Configuration;
using Sitecore.LayoutService.ItemRendering.ContentsResolvers;
using Sitecore.Mvc.Presentation;
using System.Collections.Generic;
using Foundation.Macaw.Dictionary.Helpers;
using Foundation.Macaw.Items.Interfaces;
using Foundation.Macaw.Modeling.Helpers;
using Foundation.Macaw.Modeling.Interfaces;
using Foundation.Macaw.Modeling.Models.ViewModels;
using System.Web.Mvc;

namespace Macaw.Sitecore.LayoutService.ItemRendering.ContentsResolvers
{
    public class CustomRenderingContentsResolver : RenderingContentsResolver
    {
        protected readonly IItemService _itemService;
        protected readonly IFeatureModelService _featureModelService;

        public CustomRenderingContentsResolver()
        {
            _itemService = DependencyResolver.Current.GetService(); 
            _featureModelService = DependencyResolver.Current.GetService(); 
        }

        public override object ResolveContents(Rendering rendering, IRenderingConfiguration renderingConfig)
        {
            var datasource = !string.IsNullOrEmpty(rendering.DataSource)
                ? rendering.RenderingItem?.Database.GetItem(rendering.DataSource)
                : null;

            var boilerplate = new {
                    datasource.ID,
                    datasource.Name,
                    Datasource = GetItemViewModel(),
                    Parameters = RenderingParametersModelHelper.GetRenderingParameters(), 
                    Dictionary = DictionaryItemsHelper.GetRenderingDictionaryItems(), 
                };

            object json =  base.ResolveContents(rendering, renderingConfig); 

            return new { fromContentResolver = json, macaw = boilerplate };
        }

        private ItemViewModel GetItemViewModel()
        {
            var item = _itemService.GetLayoutItem();
            return ViewModelHelper.GetItemViewModel(item);
        }

    }
}

Just drop the dll in the bin folder and make sure the binding in the resolver item in the content editor matches. 

Step 3: Then let's move to the rendering and select our created item:
Below is screenshot for reference.


Step 4: Now let's fill in the fields of the item we had:



Step 5: And finally, let's request our data from the API:




Conclusion:  From the code you can see the output. The first one is the resolved data by Sitecore  JSS inbuilt (fromContentResolver) and the second part is the contents that are resolved by the custom logic (macaw). There are two things that stand out right away when you look at the field structure returned from the layout service. The data in the fromContentResolver part hold all field values in a list having its name and a value property which exposes the value. In addition, it also got the data from the rest of the resolved items from my custom logic. The custom logic, however, holds business logic like inheritance of field values. This means that when the SEO title is blank it will take the title of the parent.

Thanks
Have a Happy LearningšŸ˜Š


Comments

Popular posts from this blog

Deleting solr documents from Solr Admin

Uninstallation of Installed Sitecore Instance Using SIA(Sitecore Install Assistant)

How to Implement Custom Personalization rule in Sitecore