Tags: Søk

Edit mode search for Episerver page id

In Episerver CMS, the search bar above the page tree in edit mode makes it easy to locate content without browsing the page tree.

You can search using the page name, content id, or other properties.

Søker etter et tall i søkefeltet over sidetreet

When searching for the content id, especially shorter ones, you could get a lot of hits on other properties than the content id.

Searching for «8» in a fresh Alloy site gives me a long list, and I can not tell which one is the content with id 8 without checking them all.

Search in the page tree for the number 8, yields several results

When I am searching for an integer, I want only the page with that specific content id. I can accomplish that by creating my own search provider, taking complete control over the search, like this:

public class CustomPageSearchProvider : PageSearchProvider
{
   private readonly IContentRepository _contentRepository;

   public override string Category => "Pages, id first";

   public override string Area => "CMS/pages";

   public override IEnumerable<SearchResult> Search(Query query)
   {
      if (int.TryParse(query.SearchQuery, out var contentId))
      {
         var result = _contentRepository
            .GetLanguageBranches<IContent>(new ContentReference(contentId))
            .Where(x => x != null).OfType<PageData>().ToList();

         if (result.Any())
         {
            return result.Select(CreateSearchResult);
         }
      }

      return base.Search(query);
   }
}

The Category is just the name of our search provider visible in admin mode. Area tells Episerver what kind of provider this is. Search() is where the searching, or in this case ContentLoading takes place.

If the user does not search for an integer, or we can not find any content with the requested id that inherits PageData, we simply fall back to the result provided by the default PageSearchProvider.

In order to access IContentRepository, I add this constructor. The property exists in the base class, but it is private.

public CustomPageSearchProvider(
    LocalizationService localizationService,
    ISiteDefinitionResolver siteDefinitionResolver,
    IContentTypeRepository<PageType> pageTypeRepository,
    EditUrlResolver editUrlResolver,
    ServiceAccessor<SiteDefinition> currentSiteDefinition,
    IContentRepository contentRepository,
    ILanguageBranchRepository languageBranchRepository,
    SearchHandler searchHandler,
    ContentSearchHandler contentSearchHandler,
    SearchIndexConfig searchIndexConfig,
    UIDescriptorRegistry uiDescriptorRegistry,
    LanguageResolver languageResolver,
    UrlResolver urlResolver,
    TemplateResolver templateResolver)
    : base(
    localizationService,
    siteDefinitionResolver,
    pageTypeRepository,
    editUrlResolver,
    currentSiteDefinition,
    contentRepository,
    languageBranchRepository,
    searchHandler,
    contentSearchHandler,
    searchIndexConfig,
    uiDescriptorRegistry,
    languageResolver,
    urlResolver,
    templateResolver)
{
    _contentRepository = contentRepository;
}

Finally, I enter the admin mode to tell Episerver to use my new search provider. Locate the Search Configuration, on the Config tab.

Search Configuration in Episerver admin mode

Then, I drag and drop my new search provider to the top of the list. It is hardly intuitive, but that is how it works! Remember to hit save.

An animation of drag-and-drop search providers

Then, searching for «8» again presents one single result.

Search in the page tree for the number 8, yields only one hit

Searching anything other than a number, the search will work exactly like before. If you prefer, you could implement something that does id-only-search when the syntax is id8id=8 or similar.

If you want fallback to Episerver Search & Navigation (formerly Find) instead of Episerver Search, extend EnterprisePageSearchProvider instead of PageSearchProvider.

 

Happy searching!