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.
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.
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.
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.
Then, searching for «8» again presents one single result.
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 id8
, id=8
or similar.
If you want fallback to Episerver Search & Navigation (formerly Find) instead of Episerver Search, extend EnterprisePageSearchProvider
instead of PageSearchProvider
.
Happy searching!