Sitecore query for fields and custom TreeListEx control to support queries

One of the things that I’ve always had to deal with multisite solutions is handle the METADATA (or a set of assets) folder for each site – that is, to make sure that each site correctly uses its own METADATA folder in all the list fields in the content editor. In order to do this, you’ll need to put queries in the Source field for each list field. If you have a METADATA folder for each site, you’ll need the path you put in the the Source field needs to be relative to the item that is being edited. The way to do this is to put sitecore queries instead of absolute/hard-coded paths. There are a two different types of queries that Sitecore supports:

1. An enhanced syntax using parameterized datasource

This is basically a querystring style format with parameters you can pass into the source, along with the path and it uses the parameters to filter the resulting list. Mark Ursino has a really good blog post on its usage.

2. query: or fast: syntax

Some of the fields also support the more versatile query: or fast: syntax, but unfortunately, not all of them do. THe fields that support the query syntax are:

  • Droplist
  • Grouped Droplist
  • DropLink
  • Grouped Droplink
  • Checklist
  • Multilist

The ones that do not support query: or fast: queries are:

  • TreeList
  • TreeListEx
  • DropTree

So – what to do? Well, Sitecore being as extensible as it is, it is pretty easy to make a custom control that can support this. John West has an approach to make relative fast queries work, by adding a custom pipeline processor.

An article in the Sitecore scrapbook gives a way to override the ‘Source‘ property of the TreeList control – whenever there is a query in the source field, the override property executes the query and then sets the source parameter for the control to use. If you inspect the code, notice that in the ‘get‘ method of the new ‘Source‘ property, we use the base property the control provides called ‘ItemID‘, which basically points to the context item.

The TreeListEx control works a little differently, because the control doesn’t actually load the tree until the user clicks the ‘edit‘ button, so this property doesn’t exist. I was going crazy trying to find out how to get the context item, and eventually found (with the help of John West) that majority of the context fields are available in Sitecore in the viewstate – all you have to do is expose it as such:

        public string ItemID
        {
            get
            {
                return StringUtil.GetString(this.ViewState["ItemID"]);
            }
            set
            {
                Sitecore.Diagnostics.Assert.ArgumentNotNull(value, "value");
                this.ViewState["ItemID"] = value;
            }
        }

Now that there is a handle on the ItemID, you can just run the same statement for the TreeList control.

There is a another point to consider, which is the links database. Now, instead of creating a new control like the article states, you can just override the existing TreeList and TreeListEx control and don’t have to worry about anything else. However, if you want to add your control, then you will need to consider the links database. The links database tracks links for all sorts of items Sitecore, one of the things it tracks is field usage. So when you go to delete it, it will pop a message saying that the item you are deleting is being used by other items. If you add your own control, then Sitecore doesn’t know about it anymore, and doesn’t track it. This can be easily solved as well, by adding some field types definitions in the /App_config/FieldTypes.config:

<fieldType name="Treelist with Source Query" type="Sitecore.Data.Fields.MultilistField,Sitecore.Kernel" />
<fieldType name="TreelistEx with Source Query" type="Sitecore.Data.Fields.MultilistField,Sitecore.Kernel" />

Alternatively, you can add your own config file in the /App_config/Include folder:

<configuration>
  <sitecore>
    <fieldTypes>
      <fieldType name="Treelist with Source Query" type="Sitecore.Data.Fields.MultilistField,Sitecore.Kernel" />
      <fieldType name="TreelistEx with Source Query" type="Sitecore.Data.Fields.MultilistField,Sitecore.Kernel" />
    </fieldTypes>
  </sitecore>
</configuration>

Note: Don’t put the namespace of your custom class in the FieldTypes.config file – you need to put the base class that it inherited from.

An edited version of this post also appears on 1000 lines of code

One thought on “Sitecore query for fields and custom TreeListEx control to support queries

Leave a comment