Showing posts with label SXA. Show all posts
Showing posts with label SXA. Show all posts

Monday, April 27, 2020

Sitecore SXA Search - Custom SearchQueryToken resolver.

Sitecore SXA provided a few OOTB search query token resolvers as mentioned below.
  1. TaggedTheSameAsCurrentPage|SxaTags
  2. TaggedWithAtLeastOneTagFromCurrentPage|SxaTags
  3. UnderCurrentPage
  4. ExcludeCurrentPage
  5. ItemsOfTheSameTemplateAsTheCurrentPage
  6. ItemsWithTheSameValueInField|FieldName
The resolveSearchQuery tokens basically is a pipeline used to add search filters. This pipeline is defined in the Sitecore.XA.Foundation.Search.config file. 
I've added a new one which is ItemsWithTheSameValueInQueryString|FieldName



Benefit- This custom search resolver can be used anywhere where we want to search/ or filter the SXA result based on the query string (Field and Value).

Example - https://website/searchresult?name1=name1Value&name2=name2Value.

Implementation - Add a new class and implement the ResolveSearchQueryTokensProcessor


 public class ItemsWithTheFieldAndValueInQueryString : ResolveSearchQueryTokensProcessor
    {
        protected string TokenPart { get; } = "ItemsWithTheSameValueInQueryString";

        [SxaTokenKey]
        protected override string TokenKey => FormattableString.Invariant(FormattableStringFactory.
            Create("{0}|FieldName", "ItemsWithTheSameValueInQueryString"));


        public override void Process(ResolveSearchQueryTokensEventArgs args)
        {
            if (args.ContextItem == null)
                return;

            for (var index = 0; index < args.Models.Count; ++index)
            {
                var model = args.Models[index];
                if (!model.Type.Equals("sxa", StringComparison.OrdinalIgnoreCase) || !ContainsToken(model)) continue;
                var inputTokenFields = model.Value.Replace(TokenPart, string.Empty).TrimStart('|');
                var fieldNames = inputTokenFields.Split(',').ToList();
                if (HttpContext.Current.Request.Url != null)
                {
                    var queryCollection = HttpUtility.ParseQueryString
                        (HttpContext.Current.Request.Url.Query);

                    NameValueCollection queryCollectionReferrer = null;
                    if (HttpContext.Current.Request.UrlReferrer != null)
                    {
                        queryCollectionReferrer = HttpUtility.ParseQueryString
                       (HttpContext.Current.Request.UrlReferrer.Query);
                    }
                    

                    foreach (var field in fieldNames)
                    {
                        if (!string.IsNullOrWhiteSpace(field) && !string.IsNullOrWhiteSpace(queryCollection[field]))
                        {
                            args.Models.Insert(index, BuildModel(field.ToLower(), queryCollection.Get(field)));
                        }
                        else if(queryCollectionReferrer != null && !string.IsNullOrWhiteSpace(field) && queryCollectionReferrer.AllKeys.Contains(field) && !string.IsNullOrWhiteSpace(queryCollectionReferrer[field]))
                        {
                            args.Models.Insert(index, BuildModel(field, queryCollectionReferrer.Get(field)));                            
                        }

                    }

                }

                args.Models.Remove(model);
            }
        }
        protected virtual SearchStringModel BuildModel(string replace, string fieldValue)
        {
            return new SearchStringModel("custom", FormattableString.Invariant(FormattableStringFactory.Create("{0}|{1}", replace, fieldValue)))
            {
                Operation = "must"
            };
        }

        protected override bool ContainsToken(SearchStringModel m)
        {
            return Regex.Match(m.Value, FormattableString.Invariant(FormattableStringFactory.Create("{0}\\|[a-zA-Z ]*", "ItemsWithTheSameValueInQueryString"))).Success;
        }
    }

Registration -


 <sitecore role:require="Standalone or ContentDelivery or ContentManagement">
    <pipelines>
      <resolveSearchQueryTokens>
        <processor type="Feature.ItemsWithTheFieldAndValueInQueryString, Namespeace" resolve="true" patch:before = "*[1]" />
      </resolveSearchQueryTokens>
    </pipelines>
  </sitecore>

patch:before = "*[1]"  -  This will be used to keep this patch on the top.


Steps to verify -

Add a SXA Search result component on the page -


You can define the search location, template and this new custom scope item -


Add all the fields required as part of query strings in this custom token resolver.



Add this scope item to the SXA search result component-



Now, you can browse the page and pass the key value in the query string, like this https://website/searchresult?name1=name1Value&name2=name2Value.
 and the SXA result component will provide the updated result :)

Saturday, February 22, 2020

SXA - High-level tree structure and steps for the theme extension.

SXA has a highly flexible structure, and it follows the Sitecore Helix principles that contain the best development process and structure for the building, testing, extending, and maintaining the implementations.

Before going further, I would like to mention the basic structure of SXA and what is required and recommendation to extend the theme.

Here is the high-level view for the SXA tree structure including content, media library and templates.




Steps to extend the SXA theme.

We can extend the theme by creating a theme extension and using the Attach Theme Extension or the Extend Site Theme action.

Extnstion theme allows us to extend the base theme without any modification to the base theme. And this can be attached to an existing site to override the part of the theme/design.

Steps - go to this path /Sitecore/media-library/Extension Themes and create a new theme.




New extended them structure will be like this -





Upload a file for fonts, images, scripts or styles.


We must use the extend site theme action to extend the existing/ or new site theme, and it will be added automatically.

There are two ways to attach the extended them to the site.

One is to create a separate module and install it. You can find more details here - Extend by a separate module, the second option is to navigate to System\Settings\Feature\Experience Accelerator and add an item extend site theme, 


To deploy them separately, we must use Attach Theme Extension action.

Create a new Attach Theme Extension and select below two values, the first field name is 'Theme that is extended' and the second one is  'Extension Themes'.

Save and refresh the experience editor. Extension theme will be applied.