Customizing Item Search in Sitecore

Daniil Raschupkin on September 26, 2017

Why

Item bucket is not just a place where the content search is used - it is where a content editor meets the search. Default search behavior is good enough for developers, but it can be tricky for a content author to get a specific item with default setup if there are thousands of items in dozens of languages. We can provide better user experience here by customizing search interface. And Sitecore (as usual) is very flexible about it.

How

Views

There are several extension points, and the first is ‘/sitecore/system/Settings/Buckets/Views’ folder. It obviously contains search result views. Any of these views can be enabled for a specific search root with ‘Enabled views’ fields (Standard Fields, ‘Item Buckets’ section):

enabled views

And naturally you can add your own views into the Views folder - just take an existing one as an example because HTML and JavaScript used there are not that simple.

Facets

Next thing to add is a Facet (stored in ‘/sitecore/system/Settings/Buckets/Facets’ folder). For example, you want to add a facet to filter products by brand. First - make sure your Brand field is stored in ‘sitecore_master_index’ so you can use it as a filter. In most cases such field will be some kind of reference field. Then you will add an item to the Facets folder and fill the ‘Field Name’ field (with the field name how it is stored in index). Now enable new facet for a bucket - select in Facets field (Indexing section).

add facet

Search anything in your bucket and you will see your Brand facet. Most probably you will be disappointed - it will show GUIDs instead of nice brand names.

brand facet ids

It works like this because Sitecore just makes a search facet on index and by default your link fields will be stored as GUIDs there. Easy workaround is to add ComputedIndexField to the index, and your ComputedIndexField will produce brand name instead of item ID.

You can patch indexing configuration:

      
	<contentSearch>
  	<indexConfigurations>
    	<defaultSolrIndexConfiguration>
      	<documentOptions>
        	<fields hint="raw:AddComputedIndexField">
          	<field fieldName="brand_name" returnType="string">Namespace.BrandComputedField, Namespace</field>
        	</fields>
      	</documentOptions>
    	</defaultSolrIndexConfiguration>
  	</indexConfigurations>
	</contentSearch>

  

And implementation for BrandComputedField:

      

	public class BrandComputedField : AbstractComputedIndexField
	{
    	public override object ComputeFieldValue(IIndexable indexable)
    	{
        	Item item = (Item)(indexable as SitecoreIndexableItem);
        	if (HasBrand(item))
        	{
            	string brand;
            	// get Brand name from the item
            	return brand;
        	}
        	return null;
    	}
	}

  

Now you can set facet field name to ‘brand_name’ and see user-friendly facet values.

Search Types

Next thing to help user to search is ‘/sitecore/system/Settings/Buckets/Search Types’. That thing helps to search against the specific field:

search types

And as usual, you can add an item here and specify field name and ... oops! - web service method (e.g. SearchService.asmx/getBrandValues) which will return values for the facet.

Pipelines

Another flexibility point is - for sure - pipelines defined in Sitecore.ContentSearch.config and Sitecore.Buckets.config. Some of them are ‘contentSearch.getGlobalSearchFilters’, ‘contentSearch.processFacets’, ‘buckets.dynamicFields’.

For example buckets.dynamicFields pipeline allows adding fields to a Search View.

1. Use special string in a view HTML e.g.

      
    <td class="brand">BrandNameDynamicPlaceholder</td>
  

2. Add a processor that will handle a placeholder ‘BrandName’ e.g.

      
public class BrandNameFieldProcessor : DynamicFieldsProcessor
{
	public override void Process(DynamicFieldsArgs args)
	{
    	args.QuickActions.Add("BrandName", GetBrandName(args));
	}

	protected string GetBrandName(DynamicFieldsArgs args)
	{
    	var item = args.InnerItem;

    	return GetBrandForItem(item);
	}
}
  

Note that you can return HTML here and make some postprocessing with JavaScript defined on View item (typically in footer template).

Finally

You can combine all these approaches and build any kind of search interface which will help content editors to manage content in the most efficient way.

Do you like this approach? Tell us what you think!


Do you need help with your Sitecore project?
VIEW SITECORE SERVICES