Kyle Kingsbury A Sitecore web development blog

Filtering Sitecore tree type fields by the inheritance chain


When working with the Helix design patterns, a typical situation comes up where the project will include templates in the Feature or Foundation layer that contain TreeList, TreeListEx or DropTree fields that will need to enforce selections based on a template in that module. However, due to limitations from the Sitecore fields you can only enforce selections based on specific templates, not based on templates that are inherited. This is an issue when the modules exposes a base template, that will be inherited in a higher layer, but still needs to maintain the selection enforcement.

For example, lets say I am implementing a list module within the Feature layer and it includes the templates, List and List Item, where List Item templates will be selected on the List template, I then want to enforce that only List Item‘s are selected from within the List template. Now most likely, the Project Layer will inherit the List Item template in order to provide defaults or apply site specific workflow (any number of reasons really). And therein lies the problem, when you set the source of the field within the Feature layer, it is bound to a specific template(s) but it doesn’t take into account the inheritance that usually comes with Helix.

You have a few options here, you can say screw Helix standards and just set the Template ID in the Feature or Foundation layer OR you can extend the fields to support inheritance. I’m hoping you are here because you want a solution to the problem, if so, lets get coding!

The solution

In order to extend, in this case override, the default fields for TreeList, TreeList and DropTree, we have two options:

  1. Create new Sitecore Field Types for three fields to call custom classes that inherit from the code of those Field Types
  2. Use patch configuration to have Sitecore look for our classes first before defaulting to the out of the box configuration

I prefer the second approach in this instance as it is seamless in that all current instances of TreeList, TreeListEx and DropTree fields can use this new functionality while still supporting the old functionality and you do not need to create additional fields. However, I will note that because we are changing all instances of the fields, you will need to verify that Sitecore hasn’t changed the underlying fields when upgrading (the code below was written for 7.2 and reviewed with Sitecore 7.2, 8.2, 9, and 9.3 versions).

What we are going to do is extend both base implementations so that the fields can include key value pairs. With the below extensions, we will now be able to update the fields Source property with syntax below to enforce selections by the inheritance:

Extending the DropTree field

To extend the DropTree field, we will need to create two new classes, one that inherits from the Sitecore.Shell.Applications.ContentEditor.Tree  and allows us to access the Source property to pull out new information and one class that inherits from Sitecore.Web.UI.HtmlControls.DataTreeview which allows us to access our new information and use it.

Add a new class called Tree (name needs to be exact):

Next we need to add the FilteredDataTreeView class:

Extending TreeList and TreeListEx

Extending the TreeList and TreeListEx fields is a lot more straightforward then the DropTree. We will need to add an additional class that extends the Sitecore.Shell.Applications.ContentEditor.TreeList and allows us to access the source property to pull out the additional filters. Note: Both Sitecore fields derive from the same class.

Configuring our new Field Types

To override Sitecore’s default fields seamlessly, we need apply a patch configuration to the controlSources node that inserts a location to search before Sitecore’s fields are evaluated. When Sitecore is looking for the implementation of it’s fields, it looks for controlSources with a prefix of “content”, so if we include our own source with the same prefix before Sitecore’s we allow Sitecore to check our namespace to see if the type exists before using Sitecore’s.

And that it, a gist is available here.

Add comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Kyle Kingsbury A Sitecore web development blog
Sitecore MVP 2019 - Technology

Recent Posts