March 18, 2014
Have you ever wanted to dynamically set the source for a Sitecore field, such as a Treelist or a Droplist, but didn’t quite get the results you wanted? The best solution is to extend the Sitecore field, by creating a custom class that inherits from the desired field type. Here is how it is done.
The Set Up
In this situation, I am working within a multi-site solution. The content structure of each site within the instance is the same. I have multiple content items throughout each site that are based on a single data template. On this data template is a Treelist field that is used to reference items that only reside within the parent site of any item created based on the template. For example – The Treelist Field on Item-A, which resides within Site-A, contains only Site-A’s children, while the Treelist Field on Item-B, which resides within Site-B, contains only Site-B’s children. Both Item-A and Item-B are based on the same template and use the same Treelist Field. Confused yet?
I will extend the Treelist Sitecore field and write a query to pull its datasource. To do this, first create a custom class that will inherit from the Sitecore field type that you want to extend. In this instance, we are extending the Treelist Field, so we will reference the Sitecore.Data.Items and Sitecore.Shell.Applications.ContentEditor namespaces
And create a new public class named ExtendedTreeList, that inherits from the Sitecore TreeList field (Sitecore.Shell.Applications.ContentEditor).
public class ExtendedTreeList : TreeList
Now we need to return the source items based on the value that will be entered into the Source field when the field type is used. We need to create a new public string property.
public new string Source
This property gets the TreeList’s Source property and sets the value based on a query or a simple link path. First we check to see if the value of the Source property starts with “query:”. If it does not, then we return the result of the value entered.
base.Source = value;
If the value does start with “query:”, we use that value to query the content tree based on the associated item, and return the result as the source. We do that by getting the associated item from the ItemID property on the ExtendedTreeList Class.
Item associatedItem = Sitecore.Context.ContentDatabase.Items[this.ItemID];
Once we have our item to base our query on, we want to run our query within the SelectSingleItem method of the item’s axes, to get the desired source item. –
Item itemQueried =associatedItem.Axes.SelectSingleItem(value.Substring("query:".Length));
If the queried item exists, then we set and return the TreeList’s Source property to the full path of the item.
if (itemQueried != null)
base.Source = itemQueried.Paths.FullPath;
Now that we have our class, we need to create our custom sitecore field use this class. To do this, make a copy of the field type that you want to extend. In our instance, duplicate the Treelist field (/sitecore/system/Field types/List Types/Treelist) and change the name of the copy to Extended Treelist. Clear the control value, and enter the name of the assembly where the class lives in the Assemble field, and the full class path in the Class field. Then, create a field on a data template that uses the Extended Treelist field type, and create a query to pull the parent item of the associated item.
For example - query:./ancestor-or-self::*[@@templatekey='website']/Global/Content/SiteSpecificItems
This will return the ‘SiteSpecificItems’ for only the parent site of the item, in which the field sits on.
Hope this helps! Have questions? Let us know in the comment section.
comments powered by