World is now on Opti ID! Learn more

Manoj Kumawat
Jul 26, 2019
  32
(0 votes)

Making use of TypeConventionBuilder to include a field with Find

The prerequisite for this post is a basic knowledge of Episerver.Find.

Yesterday I came accross with an issue with Episerver.Find filters. If you've ever faced issues with XhtmlString values with Episerver.Find then this blog post may help you.

I had an XhtmlString as one of the properties within the block as follows - 

[CultureSpecific]
[Display(
 Name = "Title",
 Description = "Title to display.",
 GroupName = SystemTabNames.Content,
 Order = 400
)]
public virtual XhtmlString Title { get; set; }

And I wanted to sort the blocks based on Title (typeof(XhtmlString)) with Find query - 

SearchClient.Instance.Search<MyCustomBlock>()
.For(searchTerm)
.OrderBy(c => c.Title)
.GetContentResult<MyCustomBlock>();

I experienced this wouldn't sort the blocks based on OrderBy Title. Because the string type here would return Xhtml elements and ultimately this would not sort it properly. 

In case if I had the Title as plain string property in block then it should have sorted it as expected. But I didn't like the idea to add any additional field of type string instead of XhtmlString to existing block.

So what should have been done?

Keeping this question in mind, I posted a forum post and as expected this finally put the results in. I can't thank enough to Paul to sort this out for me. 

Here is how it worked

If you could get rid of those HTML elements anyhow within the XhtmlString then it would definitely be a way to go - 

Step 1

Creating an extension method to strip out HTML from XhtmlString - 

 public static class SearchExtensions
    {
        public static string StripHtml(this XhtmlString htmlField)
        {
            return htmlField == null ? string.Empty : EPiServer.Core.Html.TextIndexer.StripHtml(htmlField.ToHtmlString(), 1000);
        }
    }

This is using an existing method TextIndexer class to strip out those HTML elements. Which returns up to 1000 characters (which should be easily sufficient for sorting).

Step 2

Create an InitializableModule that would use TypeConventionBuilder to include a field in Episerver.Find Indexed contents and use the extension method created above - 

[InitializableModule]
    [ModuleDependency((typeof(EPiServer.Web.InitializationModule)))]
    public class InitialiseSearch : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {
            SearchClient.Instance.Conventions.ForInstancesOf<MyCustomBlock>().IncludeField(x => x.Title.StripHtml());
       
        }

        public void Uninitialize(InitializationEngine context)
        {
        }
    }

This will include field to find index with the key - Title.StripHtml$$string and this is the key that would do our job done.

Step 3

Modifying Find query to use this extension method - 

....
.OrderBy(c => c.Title.StripHtml())
Step 4

Now you would need to reindex your contents with the scheduled job from Episerver's Admin area - EPiServer Find Content Indexing Job

After you've reindexed, It modifies the way the content is indexed, adding in a field to the content items in the index called "Title.StripHtml$$string". When you search or order on Title.StripHtml(), it doesn't run the extension method, instead it looks for the "Title.StripHtml$$string" field. If you haven't reindexed, that field won't be there.

Verifying the index - 

Go to Episerver Find/overview and click on Explore and then search for your block. This should have the field added to the Find index and look closely it is a plain string now.

Have a great day!

Jul 26, 2019

Comments

Please login to comment.
Latest blogs
Make Global Assets Site- and Language-Aware at Indexing Time

I had a support case the other day with a question around search on global assets on a multisite. This is the result of that investigation. This co...

dada | Jun 26, 2025

The remote server returned an error: (400) Bad Request – when configuring Azure Storage for an older Optimizely CMS site

How to fix a strange issue that occurred when I moved editor-uploaded files for some old Optimizely CMS 11 solutions to Azure Storage.

Tomas Hensrud Gulla | Jun 26, 2025 |

Enable Opal AI for your Optimizely products

Learn how to enable Opal AI, and meet your infinite workforce.

Tomas Hensrud Gulla | Jun 25, 2025 |

Deploying to Optimizely Frontend Hosting: A Practical Guide

Optimizely Frontend Hosting is a cloud-based solution for deploying headless frontend applications - currently supporting only Next.js projects. It...

Szymon Uryga | Jun 25, 2025

World on Opti ID

We're excited to announce that world.optimizely.com is now integrated with Opti ID! What does this mean for you? New Users:  You can now log in wit...

Patrick Lam | Jun 22, 2025

Avoid Scandinavian Letters in File Names in Optimizely CMS

Discover how Scandinavian letters in file names can break media in Optimizely CMS—and learn a simple code fix to automatically sanitize uploads for...

Henning Sjørbotten | Jun 19, 2025 |