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):
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).
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.
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:
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!