Extending Computed Fields in Sitecore By Adding Parameters

Computed Fields In Sitecore

The purpose of computed fields is to create pre-calculated values when working with indexes. Such approach allows to proceed with the search though distributed data or even when some data is outside the Sitecore (data from the external services could be taken into the Sitecore search engine).

There are many interesting use-cases of how to use computed indexes. I’m going to share some tips to help people get the most of them.

Anatomy Of A Computed Field

By default computed field a limitation – poor re-usability. This is because it’s doesn’t naturally lend itself to variable inputs.

It looks like this with fieldName being the only parameter. This controls the name of the field with the value output by Sitecore.ContentSearch.ComputedFields.Culture will be stored.

<field fieldName="culture">Sitecore.ContentSearch.ComputedFields.Culture,Sitecore.ContentSearch</field>

We’ll look at how to add parameters to computed field to make them reusable across different context.

Adding Custom Parameters To A Computed Field

Below there is a source code that describes the simple example of how to pass custom parameters to achieve reusability.

using System;
using System.Xml;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.ComputedFields;
using Sitecore.Xml;

namespace AndreyVinda.Search.ComputedFields
{
 public class CustomParameterComputedField : AbstractComputedIndexField
 {
 public string CustomParameter { get; set; }

 public CustomParameterComputedField(XmlNode configNode) : base(configNode)
 {
 this.CustomParameter = XmlUtil.GetAttribute("customerParameter", configNode);
 }
 public override object ComputeFieldValue(IIndexable indexable)
 {
 return String.Format("We added the custom parameter: {0}", CustomParameter);
 }
 }
}

The main milestones from the code above are the following:

  • Inheritance of the abstract class AbstractComputedIndexField which implements the IComputedIndexField interface
  • Usage of a custom constructor with an XmlNode argument to load the customerParameter value from the config
  • The ComputeFieldValue() method returns its value into the fieldName which is set in AbstractComputedIndexField

Creating A Customizable Date Using A Computed Field

Let’s walk-through a complete real world example. In the following example there is a definition of a computed field that outputs a DateFieldfrom Sitecore into any format. Let’s start with the config.

<field fieldName="_EventStartLongDateTime" toStringFormat="dddd, MMMM d yyyy h:mm tt">AndreyVinda.ComputedFields.ComputedDateField</field>
<field fieldName="_EventStartTime" toStringFormat="h:mm tt">AndreyVinda.ComputedFields.ComputedDateField,GetFishtank</field>

And here is a complete Computed Field class that uses a toStringFormat.

This time we’ll implement the IComputedIndexField ourselves and not use the abstract base class.

using System.Xml;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.ComputedFields;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.Xml;

namespace AndreyVinda.ComputedFields
{
    public class ComputedDateField : IComputedIndexField
    {
        public string FieldName { get; set; }
        public string ReturnType { get; set; }
        public string ToStringFormat { get; set; }

        public const string SpecialDateField = "Special Date";

        public ComputedDateField(XmlNode configNode)
        {
            this.FieldName = XmlUtil.GetAttribute("fieldName", configNode);
            this.ReturnType = XmlUtil.GetAttribute("returnType", configNode);
            this.ToStringFormat = XmlUtil.GetAttribute("toStringFormat", configNode);
        }

        public virtual object ComputeFieldValue(IIndexable indexable)
        {
            Item item = (Item)(indexable as SitecoreIndexableItem);
            if (item == null)
                return (object)null;

            var itemField = item.Fields[SpecialDateField];
            if (itemField == null) return null;

            var dateField = (DateField) itemField;

            return (object) dateField.DateTime.ToString(ToStringFormat);
        }
    }
}

In this specific case, we’re rending dates on the client-side in a number of views. Depending on the view, we want to display the date information in different ways. It makes sense to handle the date transforms once with an extensible computed field instead repeated JavaScript date formatting.

This outputs of “Sunday, February 18 2017 4:00 PM” and “4:00 PM” respectively.

And of course there are better, more-powerful use-cases than what I’ve laid out above.

Enjoy!

Advertisements

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