Wednesday, November 6, 2019

Custom SXA Scriban extensions

Sitecore - SXA & Scriban


As explaining in the what's new post on SXA 9.3 one of the major new features in the Sitecore Experience Accelerator version 9.3 is the rendering variant with a Scriban template.

Sitecore's SXA team provided a whole set of extensions that will help you get almost anything done. And if that is not the case, you can easily write your own extension and that is what I will show you here.

We'll create a custom function that can optionally utilize the Sitecore context and an extension function to call on items in Scriban.

Custom Scriban context function

A context function can perform any logic based on the parameters it receives using the Sitecore context if needed. Let's see a simple example:

Code

using Scriban.Runtime;
using Sitecore.XA.Foundation.Abstractions;
using Sitecore.XA.Foundation.Scriban.Pipelines.GenerateScribanContext;

public class ScribanMeow : IGenerateScribanContextProcessor
{
    private readonly IContext context;

    public ScribanMeow(IContext context)
    {
        this.context = context;
    }

    public void Process(GenerateScribanContextPipelineArgs args)
    {
        var meow = new MeowIt(Meow);
        args.GlobalScriptObject.Import("sc_meow", (Delegate)meow);
    }

    public string Meow(string key)
    {
        return key + " Miauw";
    }

    private delegate string MeowIt(string key);
}
We create a class implementing the IGenerateScribanContextProcessor. We inject the IContext in our constructor. In this example we're not using it, but this shows that you can if you need to. The Process function will attach our delegate to the Scriban function that we can name as we want (in this example the name is "sc_meow").

The delegate can have parameters as needed - here just a string but have more and/or other object types. The implementation of the delegate contains the logic you want performed by the function (in this example case we are just meowing the given text).

Config

<sitecore>
  <pipelines>
    <generateScribanContext>
      <processor type="Sxa93.ScribanMeow, Sxa93" resolve="true" />
    </generateScribanContext>
  </pipelines>
</sitecore>
We are placing our processor in the generateScribanContext pipeline - don't forget to add the resolve element if you want the context to get resolved in your constructor.

Usage

Once this is all done, we can use our function by calling it in a Scriban template. In our example that would be like {{ sc_meow "Key" }}.



Custom Scriban item member

An item member for Scriban is like an extension method on the Item class in C#. It's a function that gets an item and returns a value based on some logic.

Code

using Sitecore.XA.Foundation.Abstractions;
using Sitecore.XA.Foundation.Scriban.Pipelines.GetScribanItemMembers;

public class GetUpdated : GetScribanItemMember
{
    private readonly IContext context;

    protected override string MemberName => "updated";

    public GetUpdated(IContext context)
    {
        this.context = context;
    }

    protected override void Resolve(GetScribanItemMembersPipelineArgs args)
    {
        if (args.Mode == MemberMode.Name)
            args.Members.Add(MemberName);
        else
            args.MemberValue = (object) args.Item.Statistics.Updated;
    }
}
We create a class inheriting from GetScribanItemMember. We inject the IContext in our constructor. In this example we're not using it, but this shows that you can if you need to. We override the MemberName to the name we want for our extension (in this example "updated") and implement the abstract Resolve function. In this function we can place our logic - anything we want to get some output (in this example we return the updated date from the item statistics).

Config

<sitecore>
  <pipelines>
    <getScribanItemMembers>
      <processor type="Sxa93.GetUpdated, Sxa93" resolve="true" />
    </getScribanItemMembers>
  </pipelines>
</sitecore>
We are placing our class in the getScribanItemMembers pipeline - don't forget to add the resolve element if you want the context to get resolved in your constructor.

Usage

Once this is all done, we can use our item member by calling it in a Scriban template on an item. In our example that would be like {{ i_item.updated }} or {{ i_page.updated }} (or any other item object).


Conclusion

Sitecore has provided many useful extension inside SXA already, but if you do need to extend it you can. It's actually not that much work and very flexible.  Enjoy!


No comments:

Post a Comment