Loading...

Sitecore Experience Accelerator - Set Rendering Datasource to Parent

During recent developing on one of my Sitecore projects which is using Sitecore Experience Accelerator (SXA) I had to set datasource on a SXA rendering to items parent. This, turns out, wasn't so straightforward as one would hope.

Introduction

Sitecore Experience Accelerator (SXA) introduces couple of pipelines that resolve rendering datasource on its renderings.

  • DatasourceFromField
  • CodeDatasource
  • PageRelativeDatasource
  • QueryableDatasource

Each one of the above has its own purpose and you can read more about these pipelines in this article by Vipin Banka Sitecore Experience Accelerator – What is new in rendering data source.

We are only going to talk about PageRelativeDatasource and CodeDatasource in this article.

Using PageRelativeDatasource

First thing I looked at was PageRelativeDatasource. This pipeline allows us to use Sitecore XPath query with "page:" and "local:" prefixes. So, for example I would write something like this to set datasource to the "about" page relative to the page rendering is located -> "local:/about". Straight forward, right?

So, following that logic I could write "local:/.." to get my parent as datasource, however this only works partially (if you don't have dashes in your item name). Unfortunately, PageRelativeDatasource doesn't resolve item path correctly if it has dashes in it. This is an older Sitecore "Gotcha" and the workaround is to enclose item names with "-" dashes with "#" hash symbols. Otherwise, it will not work and datasource will not be valid. You can write your own pipeline and improve PageRelativeDatasource to resolve item names properly or you can use CodeDatasource to set you datasource to parent item.

Here is an example of XPath expression with item with "-" dashes in its name. When you enter "local:/.." as datasource PageRelativeDatasource resolves it like below.


/sitecore/content/sites/site1/home/blogs/my-test-blog/..

So, if your rendering is on /sitecore/content/sites/site1/home/blogs/my-test-blog the above XPath is not a valid datasource. In order for the above XPath to be valid it would have to look like this:


/sitecore/content/sites/site1/home/blogs/#my-test-blog#/..

Enclosing the item name with "#" hash symbols makes this XPath expression valid.

Using CodeDatasource

Fortunately, we can use CodeDatasource to get items parent and set it as datasource. This is pretty straightforward to implement. Here is the code which sets your items parent as datasource.


using System.Collections.Generic;
using Sitecore.Buckets.FieldTypes;
using Sitecore.Data.Items;

namespace Common.Foundation.SxaExtensions.Datasources
{
    public class ParentDatasource : IDataSource
    {
        public Item[] ListQuery(Sitecore.Data.Items.Item item)
        {
            var l = new List<Item>();
            // add parent item to the list
            if (item.Parent != null)
            {
                l.Add(item.Parent);
            }
            return l.ToArray();
        }
    }
}

And once you put that code somewhere in your solution (hopefully solution based on Helix principles :) ) all you have to do is set datasource on the rendering like so (make sure you update namespace to your project)

Summary

Sitecore Experience Accelerator is getting better and better with each release and until Sitecore fixes the PageRelativeDatasource to enclose item names with "-" dashes with "#" hash symbols you can use CodeDatasource or write your own pipeline to get parent datasource.

Disclaimer
This is a personal blog. The opinions expressed here represent my own and not those of people, institutions or organizations that the owner may or may not be associated with in professional or personal capacity, unless explicitly stated.. In addition, my thoughts and opinions change from time to time I consider this a necessary consequence of having an open mind. This blog disclaimer is subject to change at anytime without notifications.