3

I want to have a list of articles that could be located anywhere throughout the website with a particular tag associated to it. I don't want to have to have a specific query for each and every tag however.

So I have a page - with a page listing rendering added to it. It's source type is set to an Item query: enter image description here

I know how to have a static query for one particular tag:

enter image description here

But that would mean having to create a new item query for every tag that I wanted to filter on.

I had tried to get the sxa token to work in an item query ie:

enter image description here

But it always returns no results (even though my indexed data has the appropriate tags in its data).

I also tried using Search scope

enter image description here

but scope doesn't seem to be able to be associated to a page listing. Tried using the search results rendering - but that seems to require a base search query, and my page will not have a search querystring to drive a search which could then be filtered to sxa tag.

I would have thought that there was a way of displaying a list associated to an sxa tag without having to write custom code so I'm hoping I've missed something obvious.

Additional Information. My listing page is the generic page template that came out of the box as Page - and inherits _Searchable. My article page is a custom template type. It inherits all the SXA base templates that the Page out of the box came with. So it also inherits from _Searchable.

My tags are defined under my SXA Site/Data/Tags item:

enter image description here

My page that conatins the listing has this tag. enter image description here

As does my article page enter image description here

These items are indexed with the tag data in the SXA Master index. But my query is returning no results when using the SXA token search in the Item Query for the page listing.

2
  • Can you please add screenshot of how you have tags configured and also screenshot of how tags are assigned on page? For your page do you use Page template or some custom template? Does it inherit Searchable interface template? If no, try to add it to base templates of your item template. Mar 15, 2019 at 5:48
  • Can you check the executed query in the search logs? That usually helps to debug these issues
    – Gatogordo
    Mar 15, 2019 at 9:14

1 Answer 1

3

Here are a few things I learned today that may help. (SXA 1.7.0)

  • The custom sxa: tokens shown in the UI require a pipeline to run in order for them to be resolved.
  • The pipeline that runs for the Page List component does not resolve the sxa: custom tokens.

I was able to get this to work by making the following changes:

  1. Create a new class called SearchDatasource which is a nearly identical copy of Sitecore.XA.Foundation.Search.Pipelines.ResolveRenderingDatasource.SearchDatasource, Sitecore.XA.Foundation.Search
  2. Add a reference to a service ISearchQueryTokenResolver for resolving tokens and a new function to call the resolve method
  3. Change the logic in the Process method to work with the datasource field used by the Page List.
  4. Patch in the new processor
  5. Take a nap
protected ISearchQueryTokenResolver SearchQueryTokenResolver { get; set; }

protected virtual IEnumerable<SearchStringModel> ResolveSearchQueryTokens(Item contextItem, IEnumerable<SearchStringModel> models)
{
    return SearchQueryTokenResolver.Resolve(models.ToList(), contextItem);
}

public void Process(ResolveRenderingDatasourceArgs args)
{
    Assert.IsNotNull(args, nameof(args));
    if (args.DefaultDatasource.Length <= 1 || !args.DefaultDatasource.Contains("sxa:"))
        return;
    var contextItem = args.GetContextItem();
    if (contextItem != null)
    {
        var searchStringModelList = new List<SearchStringModel>();
        searchStringModelList.AddRange(SearchStringModel.ParseDatasourceString(args.DefaultDatasource));
        searchStringModelList.AddRange(GetPageScope(contextItem));
        searchStringModelList = ResolveSearchQueryTokens(contextItem, searchStringModelList).ToList();
        using (var searchContext = GetSearchContext(contextItem))
        {
            var startLocationItem = contextItem.Database.GetItem(ItemIDs.RootID);
            var query1 = LinqHelper.CreateQuery<ExtendedSearchResultItem>(searchContext,
                searchStringModelList.RemoveWhere(m => m.Type == "sort"), startLocationItem, null);
            var siteItem = MultisiteContext.GetSiteItem(contextItem);
            if (siteItem == null)
            {
                args.Datasource = string.Empty;
            }
            else
            {
                var datasourceSearchScopesIds =
                    GetDatasourceSearchScopesIds(MultisiteContext.GetSettingsItem(siteItem));
                if (datasourceSearchScopesIds.Count == 0)
                    datasourceSearchScopesIds.Add(siteItem.ID.ToSearchID());
                var query2 = query1.Where(BuildPathPredicate(datasourceSearchScopesIds))
                    .Where(i => i.Language == Context.Language.Name);
                var results = AddSorting(searchStringModelList, query2)
                    .Take(QueryMaxItems).Select(i => i.ItemId.ToString()).ToList();
                var listString = new ListString(results);
                args.Datasource = listString.ToString();
            }
        }
    }
    else
    {
        args.Datasource = string.Empty;
    }
}
// Add to the constructor
SearchQueryTokenResolver = ServiceLocator.ServiceProvider.GetService<ISearchQueryTokenResolver>();
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <resolveRenderingDatasource>
        <processor type="Scms.Foundation.Search.Pipelines.ResolveRenderingDatasource.SearchDatasource, Scms.Foundation.Search" resolve="true" />
      </resolveRenderingDatasource>
    </pipelines>
  </sitecore>
</configuration>

Note: If you are using a component like Snippet, you'll need to configure the datasource for the component, otherwise it will default to the snippet which is a problem because the tags live on the page.

Using this I set the data source to query:self::.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.