Indexing Blocks with EPiServer Search

This week I needed to add Blocks used on a page to EPiServer Search Index as content of the page they were used on. This is supported in Find, but as we are not using Find in this project, I needed a different solution.

First I added an extra property to my base class to hold the content of my Blocks. Note the ScaffoldColumn(false) attribute, which hides it in edit mode.

        public virtual string SearchText { get; set; }

Next I created an InitializableModule to attach some functionality to the publishing event

    public class SearchInitialization : IInitializableModule
        #region Public Methods and Operators

        public void Initialize(InitializationEngine context)
            DataFactory.Instance.PublishingPage += this.OnPublishingPage;

        /// <summary> Raises the page event. </summary>
        /// <param name="sender"> The sender. </param>
        /// <param name="pageEventArgs"> Event information to send to registered event handlers. </param>
        public void OnPublishingPage(object sender, PageEventArgs pageEventArgs)
            StandardPage page = pageEventArgs.Page as StandardPage;

            if (page == null)

            ContentArea contentArea = page.MainContentArea;

            if (contentArea == null)

            StringBuilder stringBuilder = new StringBuilder();

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

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

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

            page.SearchText= stringBuilder.ToString();

        public void Preload(string[] parameters)

        public void Uninitialize(InitializationEngine context)
            DataFactory.Instance.PublishingPage -= this.OnPublishingPage;


        #region Methods

        private IEnumerable<string> GetSearchablePropertyValues(IContentData contentData, ContentType contentType)
            if (contentType == null)
                yield break;

            foreach (PropertyDefinition current in
                from d in contentType.PropertyDefinitions
                where d.Searchable || typeof(IPropertyBlock).IsAssignableFrom(d.Type.DefinitionType)
                select d)
                PropertyData propertyData = contentData.Property[current.Name];
                IPropertyBlock propertyBlock = propertyData as IPropertyBlock;
                if (propertyBlock != null)
                    foreach (
                        string current2 in
                        yield return current2;
                    yield return propertyData.ToWebString();

            yield break;

        private IEnumerable<string> GetSearchablePropertyValues(IContentData contentData, int contentTypeID)
            IContentTypeRepository contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
            return this.GetSearchablePropertyValues(contentData, contentTypeRepository.Load(contentTypeID));


So, what’s happening here?

  • When publishing the page, I loop through all Blocks in the MainContentArea, also defined on my base class.
  • I get all values from string  properties marked "Searchable" in the Blocks and add them to the SearchText property on my base class. Note: If for some reason you don’t want a property on a Block indexed, just add [Seachable(false)] to it.
  • The value of SearchText property is added to the index and you get results also if the term you are looking for is only used in a Block on the page.

The two helper classes are from the "EPiServer.Core.ContentSearchHandler".

That’s it.


7 thoughts on “Indexing Blocks with EPiServer Search

  1. Hi there!

    I’m trying to implement this solution into my episerver site using the Alloy templates, but I keep getting an error on line 66:

    Error 81 Could not find an implementation of the query pattern for source type ‘EPiServer.DataAbstraction.PropertyDefinitionCollection’. ‘Where’ not found. Are you missing a reference or a using directive for ‘System.Linq’?

    Any idea what’s causing this error?

    Thanks in advance.


    1. Hi Emil,
      Do you have a reference to Linq in your project and a using in your class?
      You should have at least these:

      using EPiServer.Core;
      using EPiServer.DataAbstraction;
      using EPiServer.Framework;
      using EPiServer.Framework.Initialization;
      using EPiServer.ServiceLocation;
      using EPiServer.SpecializedProperties;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Text.RegularExpressions;



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google 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 )

Connecting to %s