Skip to main content

Sitecore

Sitecore Layout Service: Custom Rendering Contents Resolver

Two programmers working together with lines of code superimposed over them

In this blog-post, we would be looking at how you can create custom Rendering Contents Resolver to customize the rendering output of Sitecore’s Layout Service.

Sitecore’s Layout Service is a Headless endpoint which is responsible for providing data of the requested page or rendering in the form of a JSON object. GraphQL to get the Layout Service is available in both Sitecore Headless (JSS) in traditional Content Delivery and also in Sitecore Experience Edge product. Rendering Content Resolvers when used in combination with Layout Service expose/provide complex Sitecore Content of the rendering again in the form of a JSON Object.

Sitecore Headless provides six rendering contents resolvers, by default, and they are found here: /sitecore/system/Modules/Layout Service/Rendering Contents Resolvers.

Rendering Content Resolvers

  • Context Item Children Resolver: resolves/serializes the children of the context item
  • Context Item Resolver: resolves/serializes the context item
  • Datasource Item Children Resolver: resolves/serializes the children of the rendering’s datasource item
  • Datasource Resolver: resolves/serializes the rendering’s datasource item
  • Folder Filter Resolver: resolves items of Folder template type. The Template ID is specified in the Item Selector Query field of the resolver item in Sitecore.
  • Sitecore Forms Resolver: resolver specific to form items.

These default resolvers address the majority of situations, but while working on a JSS site, there is a significant likelihood that custom resolvers may be required. For example: obtaining the fields and details of a datasource item along with its children in a single JSON object is one highly frequent case which is not supported by any of the resolvers described above.

So, allow me to walk you through this simple process of developing a custom rendering content resolver, which entails:

  • Creating the class type where we will implement our own Sitecore content resolution mechanism.
  • Creating a Resolver Sitecore Item to allow user to select it from the list of available resolvers.

We will consider Datasource Item with Children Resolver as an example in the detailed process mentioned below.

Creating the class type where we will implement our own Sitecore content resolution mechanism:

The class should inherit the Sitecore.LayoutService.ItemRendering.ContentsResolvers.RenderingContentsResolver and must override ResolveContents method of the base class.

Code snippet of the class (please read the inline comments to know the intent of the code written):

using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.LayoutService.Configuration;
using Sitecore.LayoutService.ItemRendering.ContentsResolvers;
using Sitecore.Mvc.Presentation;

namespace Sitecore.Customizations.RenderingContentResolvers
{
  public class DatasourceWithChildrenItemResolver : RenderingContentsResolver
  {
    public override object ResolveContents(Rendering rendering, IRenderingConfiguration renderingConfig)
    {
      //check if the parameters are not null
      Assert.ArgumentNotNull(rendering, nameof(rendering));
      Assert.ArgumentNotNull(renderingConfig, nameof(renderingConfig));

      //get the datasource item
      Item datasourceItem = this.GetContextItem(rendering, renderingConfig);

      //return null object if the datasourceItem is null
      if (datasourceItem == null)
        return null;

      //initialize the JSON object to be returned with the datasourceItem details 
      JObject jobject = ProcessItem(datasourceItem, rendering, renderingConfig);

      //get the children of the datasourceItem
      IEnumerable<Item> items = GetItems(datasourceItem);
      List<Item> itemList = items != null ? items.ToList() : null;

      //return the JSON object if children do not exist
      if (itemList == null || itemList.Count == 0)
        return jobject;

      //add children item details to the JSON object and return the object
      jobject["items"] = ProcessItems(itemList, rendering, renderingConfig);
      return jobject;

    }
  }
}

 

Creating a Resolver Sitecore Item to allow user to select it from the list of available resolvers:

It is recommended to create the custom rendering resolvers in a separate folder under /sitecore/system/Modules/Layout Service/Rendering Contents Resolvers.

  • Create a new folder of /sitecore/templates/System/Layout/Layout Service/Rendering Contents Resolvers Folder type inside Rendering Contents Resolvers using the insert options.
  • Create the custom content resolver, again, using the insert options. 

Insert Custom Resolver

  • As an example, I created Datasource Item With Children Resolver. Now let’s look at the fields of the resolver items (refer the default content resolver, they are fairly intuitive with the short description provided:
    • Type: Put the namespace of the custom resolver class and its assembly like so:  Customizations.RenderingContentResolvers.DatasourceWithChildrenItemResolver, Sitecore.Customizations 
    • Include Server URL in Media URLs: checked by default.
    • Use Context Item: this field is unchecked, by default, which means that the resolver will use the datasource item(of the rendering) rather than the Context Item. When it is selected, the JSON object will include route level data. For our example, we will keep it unchecked.
    • Item Query Selector: This field allows the user to add queries which can manipulate how the content is being processed. Like for the default folder content resolver, this field contains the ID of the “Folder” item and only those items will be included while processing the Sitecore Content

Folder Resolver

             For our example, we need child items of the datasource, so we will add the query to select the children which is “/*”. All these fields are respected while serializing the rendering data in the resolver.

And your custom rendering contents resolver is ready!

It will be available in the list of resolvers in the Rendering Contents Resolver field of the rendering. With this custom resolver selected, the JSON output will include data of the datasource item along with its children.

Resolver In Rendering

 

I have taken into consideration a very simple example for the sake of simplicity. However, you may come across complex scenarios like including data from multiple sources other than the context/datasource items and its children; it can be incorporated in the ResolveContents method. The current example code returns all the fields of the child items which is an improvement area where you can return just the required fields.

I hope this blog post helps you in your Sitecore Headless journey. 

 

 

Thoughts on “Sitecore Layout Service: Custom Rendering Contents Resolver”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Neha Pasi

Neha Pasi, an Engineering Graduate working as a Senior Technical Consultant with Perficient GDC Nagpur, is a Sitecore Developer who has worked on SXA, Non-SXA and Headless websites. She is a proud and active member of Women In Tech ERG of Perficient and enjoys writing in her leisure time.

More from this Author

Categories
Follow Us