SXA Tokens in Sitecore Treelist Datasource: Enabling Multisite Compatibility

Learn how to use Sitecore Experience Accelerator (SXA) tokens in a Sitecore treelist datasource for multisite compatibility.

January 24, 2024

By Anju Thomas

Have you ever struggled with reusing components that include a treelist in Sitecore, particularly when managing multiple sites? The main issue often lies in setting the source of the treelist field on the template. It's akin to juggling too many tasks at once. This blog will provide guidance on how to resolve this issue using a custom field and SXA tokens.

The Problem

This blog discusses a common issue in Sitecore when trying to reuse components with a treelist datatype in a multisite setup. The problem occurs when the source of the treelist field is set on the template, which complicates pointing the source to multiple data folders for different sites in a multisite environment.

In a single-site environment, setting those sources is straightforward. However, in a multisite setup, you typically want the source to be relative to the site's data folder.

Treelist Datasource

SXA Tokens in Sitecore Treelist Datasource Screenshot

The Treelist field in Sitecore is a popular choice for enabling the selection of items from a tree view. It offers a user-friendly experience for editors, but configuring the root (datasource) for the tree can be complex.

You can set the Source property of a Treelist or TreelistEx field type to any number of key=value parameters separated by ampersand characters (&).

For example in situations where we want to include or exclude templates for display and selection we could make use of these parameters to get the desired results as in the datasource specified below

**datasource=/sitecore/content/Tenant/Site/Data/Content Card Folder&IncludeTemplatesForSelection=Content Card&ExcludeTemplatesForSelection=Content Card Folder**

SXA Tokens

The resolveTokens pipeline in Sitecore eXperience Accelerator (SXA) is a crucial component used to resolve tokens that can be employed in queries. Crucially, it's the backbone of creating multisite-friendly templates through the versatile use of tokens in diverse contexts. For example, it empowers the use of tokens such as $site, $tenant, $currenttemplate, $home, and $pageDesigns within the datasource of a variety of field types, including the standard Treelist fields.

SXA Tokens in a Treelist Datasource

In my current project, I'm working with a multisite setup, enhanced with Headless Sitecore Experience Accelerator (SXA). Within this setup, several of my templates are equipped with Treelist fields. By using query notation in the datasource, it's possible to employ tokens, which can be beneficial in certain scenarios.

However, an issue arises when you use this method—it results in a loss of flexibility when it comes to other parameters. This can be a significant drawback, as it limits the versatility and adaptability of the system.

In light of this problem, I've been exploring possible solutions to balance both aspects. What I'm aiming for is a method that allows the use of parameters like(IncludeTemplatesForSelection and IncludeTemplatesForDisplay) to define potential templates. At the same time, I would like to continue using tokens to establish the parent.

Therefore, the challenge lies in finding a balanced approach that satisfies these two requirements. This would make it possible to maintain the power and flexibility of SXA tokens while also allowing for the precise control offered by parameters.

One suggested solution discussed in an excellent blog by Gert "Gatogordo" Gullentops is to return a standard path instead of null when the query result is null

public class TokenedTreelist : Sitecore.Shell.Applications.ContentEditor.TreeList
{
  public override string DataSource
  {
    get
    {
      var data = base.DataSource;
      if (!base.DataSource.StartsWith("query:", StringComparison.OrdinalIgnoreCase))
      {
        return data;
      }

      if (Sitecore.Context.ContentDatabase == null || ItemID == null)
      {
        return null;
      }

      var currentItem = Sitecore.Context.ContentDatabase.GetItem(ItemID);
      Item source = null;
      try
      {
        source = LookupSources.GetItems(currentItem, data).FirstOrDefault();
      }
      catch (Exception ex)
      {
        Log.Error("Treelist field failed to execute query.", ex, this);
      }

      return source == null ? "/sitecore/Content" : source.Paths.FullPath;
    }

    set => base.DataSource = value;
  }
}

We are actually creating a new field here called TokenedTreelist - fully using the TreeList as a base and overriding the Datasource property.

Remember to register this field in the core database, as it is new. Add an item at /sitecore/system/Field types/List Types and fill in your assembly and class information as in the screenshot below.

SXA Tokens in Sitecore Treelist Datasource Screenshot

Also, add it to the field types list in the config as

<fieldTypes>
          <fieldType patch:after="*[@name='Treelist']" name="Tokened Treelist" type="Sitecore.Data.Fields.MultilistField, Sitecore.Kernel" />
</fieldTypes>

Now if we update the source field for the Tokened Treelist as below with the site token, we would get the cards populated relative to the site’s Data folder

datasource=query:$site/Data/Content Card Folder&IncludeTemplatesForSelection=Content Card&ExcludeTemplatesForSelection=Content Card Folder

SXA Tokens in Sitecore Treelist Datasource Screenshot

SXA Tokens in Sitecore Treelist Datasource Screenshot

After following the blog up to this point, we can see the cards populating in the Tokened Treelist field as expected. However, there's an issue with the component rendering on the pages.

After some research, I understood that there is a difference in the serialized output between this new Treelist field type and the standard Treelist.

Upon examining the Sitecore context via console logging, we can observe a noteworthy difference in the serialized output produced by the standard treelist and our newly crafted field type. This discrepancy is particularly evident when comparing the nature of the returned data.

The standard treelist, in its serialized form, returns a list consisting of Guids, which are essentially unique identifiers used in software development.

On the other hand, our custom field type, when subjected to the same process, presents a stark contrast. Instead of a list of Guids, it returns an array populated with items.

This comparison underscores the distinct behaviours of these two field types when it comes to generating serialized output. The images below further illustrate this disparity.

SXA Tokens in Sitecore Treelist Datasource Screenshot

SXA Tokens in Sitecore Treelist Datasource Screenshot

The solution to this problematic situation was found by modifying the existing pipeline structure. More specifically, we resolved the issue by patching the getFieldSerializer pipeline, which is an integral part of the layoutService pipeline group. In this process, we ensured the inclusion of the newly created field type, named as Tokened Treelist. This inclusion was a critical step in addressing the problem at hand, ultimately leading to the resolution of the original issue.

<pipelines>
          <group groupName="layoutService">
              <pipelines>
                  <getFieldSerializer>
                      <processor type="Sitecore.LayoutService.Serialization.Pipelines.GetFieldSerializer.GetMultilistFieldSerializer, Sitecore.LayoutService" resolve="true">
                          <FieldTypes hint="list">
                              <fieldType patch:after = "*[@name='Treelist']" id="99">Tokened Treelist</fieldType>
                          </FieldTypes>
                      </processor>
                  </getFieldSerializer>
              </pipelines>
          </group>
      </pipelines>

Difficulties Reusing Treelist Datasource Components

This blog post discusses the difficulties of reusing components with a treelist datatype in a multisite setup in Sitecore, particularly when the treelist field's source is set on the template. Although using SXA tokens can enable multisite-friendly templates, it may limit flexibility with other parameters. A balanced solution involves using a new custom field type, the Tokened Treelist, which supports both parameters and tokens until Sitecore develops a more robust solution.

Thank you for reading!



Anju Headshot

Anju Thomas

Sitecore Web Developer

Anju is a Sitecore Developer with a Bachelor's Degree in Computer Science and over 4 years of experience in Sitecore development. She loves solving Sudoku puzzles, watching movies, eating delicious food and exploring the world.