Monday, October 14, 2019

Using SXA Search Scope in your custom component

Sitecore SXA Search Scope

Search scopes can be used to limit search results based on conditions. 
Search scopes are queries defined and stored in Sitecore. You can find them for each SXA site in  /sitecore/content/Tenant/Site/Settings/Scopes.

Each scope has a search query that can contain conditions. These conditions can be anything that can be used in queries, like the template or the location in the content tree. Scopes can be attached to search components and you can use them in a custom component as well. This gives you a way to configure the query that is performed by your code and/or reuse the query on several places.

Rendering parameters

The search scope for a rendering is set in its rendering parameters. To easiest way to add a scope to your custom rendering is adding the _Page Search Scope template as base to your rendering parameter template.

The rendering parameter will contain a string that has the guid of the item containing the search scope. This search scope is again a a string that should be transformed to a query.

Using Search Scope in custom code

You can call all the needed functions to do this yourself (it's not that much actually) but the best way is to use the search service from SXA - this will also make sure that things like resolving search tokens are covered.

To use the ISearchService implementation, we inject it in our constructor:
public SearchResultsRepository(Sitecore.XA.Foundation.Search.Services.ISearchService searchService)
{
    this.searchService = searchService
}

Now we build a SearchQueryModel that we can pass to the search service. Note that in older versions of SXA (like 1.7.1) the service did not use this model - the parameters had to be passed individually but the result should be the same.

We read the scope from the rendering parameters and pass it with some other context information to the GetQuery function. This will take care of everything needed to transform the scope into a query that can be used to get the results from the index.
var scope = Rendering.Parameters["Scope"];
var model = new SearchQueryModel
{
    ItemID = Sitecore.Context.Item.ID,
    Site = Sitecore.Context.Site.Name,
    Languages = new List { Sitecore.Context.Language.Name },
    ScopesIDs = new List { new ID(scope) }
};

var query = searchService.GetQuery(model, out var indexName);
var results = query.GetResults();
If you still want to extend the query before fetching the results, that is also an option.

Conclusion

The scope adds a configurable part to your queries, which can make your custom component a lot more flexible towards multisite or any other condition that you can now remove from the code. It's maybe not the most know feature of SXA (although you might have used it in the out-of-the-box search components), but it can be very useful even towards custom code.

No comments:

Post a Comment