Custom Scriban Object processor in SXA
Hello everyone, In this blog, we will learn one more important concepts in Sitecore SXA and i.e. Custom Scriban object. As scriban was introduced in Sitecore 9.3 SXA, more developer started using Scriban while creating rendering variants. By default Sitecore provide a number of built-in Scriban Objects which you find on the Sitecore document site Link.
Still there are time, where we need to create our own custom Scriban objects and we will see this here, how we can implement it.
Let's take a use case: Reading Dictionary directly inside Scriban template. For this we don't have any built-in object and we will implement it using custom Scriban Object.
Steps for creating Custom Scriban Object
- Creating custom Scriban processor inheriting from IGenerateScribanContextProcessor
- Registering the Processor under generateScribanContext pipeline
So lets see the code without wasting any more time.
Step 1: Create a Custom Scriban Processor (GetDictionary). Inherit the class from AddFieldRendererFunction, IGenerateScribanContextProcessor.
using Scriban.Runtime;
using Sitecore.Data.Items;
using Sitecore.XA.Foundation.Abstractions;
using Sitecore.XA.Foundation.Scriban;
using Sitecore.XA.Foundation.Scriban.Pipelines.GenerateScribanContext;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Shrikant.Foundation.Scriban.Pipelines
{
public class GetDictionary : AddFieldRendererFunction, IGenerateScribanContextProcessor
{
private IDictionary _iDictionary;
public GetDictionary(IPageMode iPageMode,IDictionary iDictionary):base(iPageMode)
{
_iDictionary = iDictionary ?? throw new ArgumentException(nameof(iDictionary));
}
public new void Process(GenerateScribanContextPipelineArgs args)
{
this.RenderingWebEditingParams = args.RenderingWebEditingParams;
RenderField renderField = new RenderField(this.RenderDictionaryEntry);
args.GlobalScriptObject.Import("sc_dictionary", renderField);
}
public string RenderDictionaryEntry(object key, ScriptArray parameters = null)
{
return this.RenderFieldImpl(_iDictionary.GetDictionaryItem(key as string),{Dictionary Phrase Field ID} , parameters);
}
private delegate string RenderField(object key, ScriptArray parameters = null);
}
}
If you see above code, we have create GetDictionary class inheriting from IGenerateScribanContextProcessor and AddFieldRendererFunction. The AddFieldRendererFunction is built in class which helps to rendered default scriban fields. So to render dictionary, we are using its RenderFieldImpl() method. The IDictionary dependency is responsible for getting the actual dictionary items from sitecore. Its basically a helper method. We are creating a Delegate RenderField which takes a method as reference(RenderDictionaryEntry) and pass the method parameter required for the implementation. Dictionary Phrase Field ID is the id of the field from Dictionary template.
Now lets create the helper method which will actually get the dictionary item. Create Interface IDictionary.cs and have GetDictionaryItem() as shown below. Create Dictionary.cs class inheriting from IDictionary interface.
public interface IDictionary{
Item GetDictionaryItem(string key)
}
using System;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.SecurityModel;
using Sitecore.XA.Foundation.Abstractions;
using Sitecore.XA.Foundation.Multisite;
using Sitecore.XA.Foundation.SitecoreExtensions.Extensions;
namespace Shrikant.Foundation.Helper
{
public class Dictionary : IDictionary
{
public IContext _context;
public IMultisiteContext _siteContext;
public AutoDictionaryRepository(IContext context, IMultisiteContext siteContext)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
_siteContext = siteContext ?? throw new ArgumentNullException(nameof(siteContext));
}
public Item GetDictionaryItem(string key)
{
Item dictionary = context == null ? _siteContext.DictionaryItem : _siteContext.GetDictionaryItem(_siteContext.GetSiteItem(context));
Database db = context == null ? _context.Database : context.Database;
if (dictionary == null)
throw new Exception("AutoDictionary requires an SXA dictionary");
var path = string.Join("/", key.Replace(".", "/").Split('/').Select(x => string.IsNullOrWhiteSpace(x) ? "" : ItemUtil.ProposeValidItemName(x)));
Item dictionaryEntryItem = db.GetItem($"{dictionary.Paths.FullPath}/{path}");
return dictionaryEntryItem ?? null;
}
}
}
If you see helper method(GetDictionaryItem()) it takes as key. The key should be basically in format where its has the full path from Dictionary domain till key name. This will help to format the key and get the path from where we can fetch the item and return the item to RenderFieldImpl()
Now lets register Scriban object in Pipelines
<pipelines>
<generateScribanContext>
<processor type="Shrikant.Foundation.Scriban.Pipelines.GetDictionary, Shrikant.Foundation" resolve="true" />
</generateScribanContext>
</pipelines>
To use the Custom Scriban Object just use {{sc_dictionary 'accordion.collapse'}}. This is just a example
Thanks for reading. Keep learning. Happy Sitecoring!!
You can check my other blogs blog related to Sitecore.
Comments
Post a Comment