Custom Multisite Multilist with Search Sitecore field

We are currently working on a multisite sitecore 7.2 with MVC solution. During this time, we came across the need to allow dynamic datasources to Multilist with search sitecore fields.
While looking out for a solution, I came across this post which give a great way of inducing queries into the datasource of a multilist with search field: Dynamic Multilist with Search.

However, we also had instances in our site, where the repository lived outside of the site node itself. So we needed to build something custom here.

For example: Sitecore Commerce Connect’s product repository lives outside of the home node:
2015-07-06_005755
Similarly, we also had video repositories for each site which live inside the Media Library.

So we ended up creating a custom field to cater to our needs here. This new field, took as input in the search location parameter – certain special tokens, which we then resolved in the code. In addition, we also used filters to filter through multiple templates – since each site might have separate template for say products etc.

In our solution in sitecore, we created a common template – Site Node – which was used to create each site’s root, and the respective Home nodes were child items of these Site Nodes.
Any external repositories which were associated with respective sites, were associated using fields on the site node.

Example, for Site 1:
2015-07-06_011233

In line with the requirements we had, we created support for 3 special tokens

  • $sitenode
  • $siteproductsrepository
  • $sitevideorepository

So basically in the datasource of this new field, we would use values like:

*************************** PRODUCTS – Multisite Multilist with Search *****************************
StartSearchLocation=$siteproductrepository&Filter=_templatename:Site1 Product|_templatename:Site2 Product

************************* Product Category – Multisite Multilist with Search ***********************
StartSearchLocation=$sitenode/Home/Products&Filter=_templatename:Site1 Product Category|_templatename:Site2 Product Category

************************* Video – Multisite Multilist with Search ***********************
StartSearchLocation=$sitevideorepository&Filter=_templatename:Video File

The code used:

namespace MySite._Classes.SBDShared.Customizations.Customized_Sitecore
{
    class MultisiteMultilistWithSearchField : BucketList
    {
        public new string Source
        {
            get { return base.Source; }
            set
            {
                if (value.Contains("$siteproductrepository"))
                {
                    var contextItem = Sitecore.Context.ContentDatabase.Items[ItemID];
                    var siteNode = SitecoreHelper.ItemMethods.GetAncestorOrSelfByTemplateId(contextItem, ConfigurationManager.AppSettings["TemplateGuid_SiteNode"]);
                    if (siteNode != null)
                    {
                        var productRepository = SitecoreHelper.ItemRenderMethods.GetReferenceField(siteNode, ISite_NodeConstants.Product_RepositoryFieldName);
                        base.Source = productRepository != null ? value.Replace("$siteproductrepository", productRepository.ID.ToString()) : value;
                    }
                }
                else if (value.Contains("$sitevideorepository"))
                {
                    var contextItem = Sitecore.Context.ContentDatabase.Items[ItemID];
                    var siteNode = SitecoreHelper.ItemMethods.GetAncestorOrSelfByTemplateId(contextItem, ConfigurationManager.AppSettings["TemplateGuid_SiteNode"]);
                    if (siteNode != null)
                    {
                        var videoRepository = SitecoreHelper.ItemRenderMethods.GetReferenceField(siteNode, ISite_NodeConstants.Video_RepositoryFieldName);
                        base.Source = videoRepository != null ? value.Replace("$sitevideorepository", videoRepository.ID.ToString()) : value;
                    }
                }
                else if (value.Contains("$sitenode"))
                {
                    const string startSearchLocationText = "StartSearchLocation=";
                    var sourceString = value;
                    var contextItem = Sitecore.Context.ContentDatabase.Items[ItemID];

                    int startSearchLocationIndex = sourceString.IndexOf(startSearchLocationText, System.StringComparison.OrdinalIgnoreCase);

                    string startSearchLocation = sourceString.Substring(startSearchLocationIndex + startSearchLocationText.Length,
                        sourceString.IndexOf("&", startSearchLocationIndex, System.StringComparison.Ordinal) - startSearchLocationText.Length);

                    var siteNode = SitecoreHelper.ItemMethods.GetAncestorOrSelfByTemplateId(contextItem, ConfigurationManager.AppSettings["TemplateGuid_SiteNode"]);

                    if (siteNode != null)
                    {
                        var sourceItem = SitecoreHelper.ItemMethods.GetItemByPathInMaster(startSearchLocation.Replace("$sitenode", siteNode.Paths.FullPath));
                        base.Source = sourceItem != null ? value.Replace(startSearchLocation, sourceItem.ID.ToString()) : value;
                    }
                }
                else
                {
                    base.Source = value;
                }
            }
        }
    }
}

2 special custom sitecore helper methods are used here:

  • GetAncestorOrSelfByTemplateId: Basically goes recursively up the content tree to find an ancestor item match by template id.
  • GetReferenceField: This method gets the item referenced in say a droplink field, by fetching the item based on the guid stored in the field.

Finally, to make this new control available in sitecore – we need to add a corresponding item in the core database (Make a copy from the similar Multilist with Search for simplicity here).
2015-07-06_014516

A corresponding config update would be required to register the prefix used above:

<sitecore>
  <configuration>
    <controlSources>
      <source mode="on" namespace="MySite._Classes.SBDShared.Customizations.Customized_Sitecore" assembly="MySite" prefix="contentExtension" />
    </controlSources>
  </sitecore>
</configuration>
Advertisements

One thought on “Custom Multisite Multilist with Search Sitecore field

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s