Indexing Blocks with EPiServer Search, revisited

While back I blogged about Indexing Blocks with EPiServer Search, this is one of my most read posts, and I use it a lot myself. But I got tired of copying the code every time, so I decided to make it more generic.

I created an attribute called “AdditionalSearchContent”.

When publishing I look for the (first) string property with this attribute.

private static PropertyInfo GetAddtionalSearchContentProperty(PageData page)
        {
            PropertyInfo keywordsMetatagProperty =
                page.GetType().GetProperties().Where(HasAttribute<AdditionalSearchContentAttribute>).FirstOrDefault();

            return keywordsMetatagProperty;
        }

private static bool HasAttribute<T>(PropertyInfo propertyInfo) where T : Attribute
        {
            T attr = (T)Attribute.GetCustomAttribute(propertyInfo, typeof(T));

            return attr != null;
        }

Next I loop through all ContentAreas, not just a specific one like in my last post, on the page and aggregate the content marked searchable. See my previous post for that piece of code.

StringBuilder stringBuilder = new StringBuilder();

ContentType contentType = this.ContentTypeRepository.Service.Load(page.ContentTypeID);

            foreach (PropertyDefinition current in
                from d in contentType.PropertyDefinitions
                where typeof(PropertyContentArea).IsAssignableFrom(d.Type.DefinitionType)
                select d)

            {
                PropertyData propertyData = page.Property[current.Name];

                ContentArea contentArea = propertyData.Value as ContentArea;

                if (contentArea == null)
                {
                    continue;
                }

                foreach (ContentAreaItem contentAreaItem in contentArea.Items)
                {
                    IContent blockData = contentAreaItem.GetContent();

                    IEnumerable<string> props = GetSearchablePropertyValues(blockData, blockData.ContentTypeID);

                    stringBuilder.AppendFormat(" {0}", string.Join(" ", props));
                }
            }

Last I add the content to the attributed property. So the only thing to do now is some attributes to a string property and you blocks will get indexed with the page they are on.

[CultureSpecific]
[ScaffoldColumn(false)]
[AdditionalSearchContent]
public virtual string SearchText { get; set; }

As always the code is available on GitHub.

It is also available on NuGet.

6 thoughts on “Indexing Blocks with EPiServer Search, revisited

  1. Thanks for posting this. It’s helping us with a project. We downloaded the NuGet version 2.0.2.0, since we are applying this to an older Epi site. The indexing works well when we publish a page. But when we only edit the block content, the index doesn’t get updated on that page. When a block is edited, how can we re-index all pages where the block gets used? Is this something you’ve addressed in a newer version? Thanks.

    Like

Leave a comment