If you are just starting with JSS coming from an MVC background you will get to a point where you need to return data to the layout service which does not come from rendering datasource or context item.
In this case, we will have to create our custom Rendering Content Resolver.
Here are a few Rendering Content Resolver out of the box from Sitecore Layout Service:
- Datasource Resolver - The default behavior, serializes the rendering's datasource item
- Datasource Item Children Resolver - Serializes the children of the datasource item
- Context Item Resolver - Serializes the context item instead of the datasource item
- Context Item Children Resolver - Serializes the children of the context item
- Folder Filter Resolver - Serializes the descendents of the datasource item, excluding folders
To create your custom content resolver we will have to inherit from RenderingContentsResolver class. Here is my sample implementation:
using Sitecore.Configuration;
using Sitecore.LayoutService.Configuration;
using Sitecore.LayoutService.ItemRendering.ContentsResolvers;
using Sitecore.Mvc.Presentation;
namespace MyNameSpace.ContentResolver
{
public class CustomResolver : RenderingContentsResolver
{
public override object ResolveContents(Rendering rendering, IRenderingConfiguration renderingConfig)
{
// In this example my items are coming from multiple sources.
var customerItem = Factory.GetDatabase("master").GetItem(new Sitecore.Data.ID("68FE0382-BDCA-4625-79C0-93DAF1FE0382"));
var linkFolder = Factory.GetDatabase("master").GetItem(new Sitecore.Data.ID("3DAFDACE-4625-4FC4-BDCA-6379684062C2"));
// ProcessItem will serialize my customerItem with layout service serialization.
// This will only return the fields that I added in my template as a JObject.
var processItem = ProcessItem(customerItem, rendering, renderingConfig);
// I only want to return the data that I need. In this case I will create a new object which consist specific data.
return new {
// I can then get the value of the field that I need.
title = processItem.Value<object>("Title"),
description = processItem.Value<object>("Description"),
email = processItem.Value<object>("Email"),
enableEmail = processItem.Value<object>("EnableEmail"),
// This will return the children of the linkFolder as a serialized JArray.
links = ProcessItems(linkFolder.Children, rendering, renderingConfig)
};
}
}
}
After creating my custom content resolver, I now have to assign it to a Rendering Content Resolver in Sitecore (/sitecore/templates/System/Layout/Layout Service/Rendering Contents Resolver).
Next, is to assign it to a JSON Rendering.(/sitecore/layout/Renderings)
After this, you can now use your JSON Rendering in your JSS Route.
Working with JSS have a different approach(mindset) than traditional MVC. In MVC we are used to working with our data with controllers and views, in JSS we will be working with Rendering Content Resolver.
Send a message in the comments if you find this helpful.
Cheers!
References:
https://jss.sitecore.com/docs/techniques/extending-layout-service/layoutservice-rendering-contents
https://andypaz.com/2020/10/21/creating-a-custom-rendering-contents-resolver/