Indexing fields directly from your pages is one thing. What about components that are commonly used on various pages, but not every page? Or unique pages for special purposes?
Instead of checking templates and using a static set of fields per page type, you can look at the datasources in the renderings and use those.
So if you have blog posts where some have summaries, and others have guest author blurbs, you can index those separately. Then if you want to have a guest author section on some other page, no changes are needed.
Another set of landing pages might have a testimonial on each, and if you wanted to reuse a testimonial on a home page or product page, no coding changes are required.
How Do We Do It?
First off, we need to get the datasources themselves
public List GetItemDatasources(Item itemToIndex, DeviceItem device)
{
RenderingReference[] renderings = null;
if (item != null && item.Fields[FieldIDs.LayoutField] != null) {
renderings = item.Visualization.GetRenderings(device, false);
}
var datasources = new List();
foreach (var rendering in renderings) {
datasources.Add(rendering.Settings.DataSource);
}
return datasources;
}
Great, now that we have the list, it's time to use it. This example uses Coveo for Sitecore, since that was the context we needed it in, but this could be used in a standard Solr setup with a little modification too.
Some of this code has been omitted for brevity, like defining the template guids and guarde code.
namespace MyProject.ComputedFields
{
public class SummaryComputedField : IComputedIndexField
{
public object ComputeFieldValue(IIndexable indexable)
{
object computedFieldValue = null;
var indexableItem = indexable as SitecoreIndexableItem;
if (indexableItem != null) {
var db = indexableItem.Item.Database;
var device = DeviceItem.ResolveDevice(db);
var datasources = ItemUtility.GetDatasources(indexableItem.Item, Device
if (datasources.Any()) {
var summaryItem = datasources.FirstOrDefault(x => x.TemplateID.Guid == SummaryTemplateId || x.TemplateID.Guid == QuickSummaryTemplateId);
if(summaryItem != null & !String.IsNullOrEmpty(summaryItem["Summary Text"]) {
computedFieldValue = summaryItem["Summary Text"];
}
}
}
return computedFieldValue;
}
}
}
There we have it! You could add more variants on this to have more computed fields, or add three datasources together to create a paragraph of text in your search result, or collect a tag cloud into keywords.
Or you could abstract this class and make a whole list of components that come out wherever you need them in your search results.