Reinoud van Dalen

February 18, 2016

Ensure your Sitecore datasource locations

A really small feature, yet very handy, of which I found myself adding over and over again. Time to put it into a nuget package so we can just install and use.

But first let’s take a moment and give credit

Because I did not invent this. I was inspired by a post from Jeremy Davis: https://jermdavis.wordpress.com/2014/02/21/improving-your-sitecore-ia-with-relative-datasource-locations/

The only thing I did was tweak it a little and make it a Nuget package. Because copying code from one project to another felt bad and we all know a kitten is being drowned in angel tears if we do.

The situation

Datasource items are a very common thing in Sitecore and the best strategy I found, on where to store them, so far is this:

  • Page data: the datasource item is stored in a ‘Page data’ folder which is a child of the current page
  • Site data: the item is stored in a ‘Site data’ folder which is a child of the current site
  • Global data: the item is stored in a ‘Global data’ folder which is somewhere probably at the same level as the site items are.

You can determine per component which locations are allowed. So if I have a component that allows any of those folders as valid datasource location then the ‘datasource location’ field value would look like this:
./Page data|query:./ancestor-or-self::*[@@templatekey='site']/Site data|/sitecore/content/Global data.

This will result in a datasource selection modal looking like this:

undefined

I’m not telling you that you should follow this strategy, nor does the package require that you do. It’s just to have a reference. Because:

What if one of those folders is not created yet?

It is highly likely that the Page Data folder will not be created by the content editors. You could make a branch to create it automatically but that requires you make a branch for every page template you have.

This solution will hook into the getRenderingDatasource pipeline and check, for each datasource location, if it’s available and if not it will try to create it using a configurable template and sorting order.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<getRenderingDatasource>
<processor type="Sc.Commons.EnsureDatasourceLocations.EnsureDatasourceLocationsProcessor, Sc.Commons.EnsureDatasourceLocations" patch:before="processor[@type='Sitecore.Pipelines.GetRenderingDatasource.GetDatasourceLocation, Sitecore.Kernel']">
<param desc="sortOrder">0</param>
<param desc="templateId">{A87A00B1-E6DB-45AB-8B54-636FEC3B5523}</param>
</processor>
</getRenderingDatasource>
</pipelines>
</sitecore>
</configuration>

The only folders it cannot create are the ones that are referenced by query, as we do not know the path to create it. So in this example 'Page data' and 'Global data' will be created if they do not exist.

Why sorting order? Well I found it useful to try and keep the Page data folder as first child of the page item it belongs to. Else it would get mixed with the other child items which I think would look a bit messy and confusing. So by default the configuration is set to 0 sorting order and using the default Folder template which comes with every clean Sitecore install.

undefined

That’s all

Nothing much to add more to this. I will be installing this package from now on instead of copying the code. Hopefully this will be useful for others as well.

Nuget: https://www.nuget.org/packages/Sc.Commons.EnsureDatasourceLocations
Source: https://github.com/RvanDalen/Sc.Commons.EnsureDatasourceLocations 

TAGS: sitecore


Comments
Mark Stiles

Nice catch with the EventDisabler. I was getting a page that kept reloading after the item was created and that's what fixed it. Kudos.