Fermer

août 28, 2022

Jeton SXA personnalisé pour la requête de portée de recherche afin de prendre en charge toutes les opérations de filtrage

Jeton SXA personnalisé pour la requête de portée de recherche afin de prendre en charge toutes les opérations de filtrage


Conditions préalables:

  • Instance Sitecore 10.2
  • Compréhension de base des éléments suivants :

Défi:

Nous pouvons fournir plusieurs filtres de recherche dans la requête de portée de recherche pour un composant de résultats de recherche SXA. Nous pouvons utiliser les jetons de recherche SXA prédéfinis dans le filtre.





Si un seul filtre de recherche commence paralors l’opération appliquée au filtre est
+doit (opération ET)
pas (pas de fonctionnement)
Rien n’est défini ou par défautdevrait (opération OU)

Le défi avec les jetons SXA prédéfinis comme ItemsWithTheSameValueInField est qu’il considère toujours l’opération « doit ». Par conséquent, même si nous basculons le filtre, c’est-à-dire changeons l’opération comme indiqué ci-dessous, cela n’affecte pas le résultat de la recherche.

1 Articlesaveclamêmevaleurdanslechampdémo

ItemsWithTheSameValueInField Démo

Il en va de même pour les jetons SXA tels que TaggedTheSameAsCurrentPage et TaggedWithAtLeastOneTagFromCurrentPage. Fondamentalement, l’implémentation de ces deux jetons est identique à l’exception du type de filtre, c’est-à-dire que l’opération a des valeurs différentes. L’opération « doit » est définie dans le cas de TaggedTheSameAsCurrentPage, et l’opération « devrait » est définie dans le cas de TaggedWithAtLeastOneTagFromCurrentPage.

La solution:

Nous pouvons implémenter de nouveaux jetons de recherche inspirés de l’implémentation de jetons prédéfinis avec quelques modifications. Nous pouvons fournir l’opération définie par l’utilisateur de l’éditeur de contenu dans la portée de la recherche comme dans les implémentations suivantes.

Le code commenté avec « définir l’opération donnée dans la portée » est la clé, et vérifiez également les autres commentaires pour référence 🙂 .

Sitecore - Comprendre les approches de développement : une perspective de Sitecore

CustomItemsWithTheSameValueInField – Pour un type de champ simple ou des types de champs où un seul ID est enregistré.

using Sitecore.ContentSearch.Utilities;
using Sitecore.Data.Fields;
using Sitecore.XA.Foundation.Search.Attributes;
using Sitecore.XA.Foundation.Search.Pipelines.ResolveSearchQueryTokens;
using System;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;

namespace CustomSXA.Foundation.Search.SearchQueryToken
{
    public class CustomItemsWithTheSameValueInField : ResolveSearchQueryTokensProcessor
    {
        protected string TokenPart { get; } = nameof(CustomItemsWithTheSameValueInField);

        protected string Operation { get; set; } = "should";

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

        public override void Process(ResolveSearchQueryTokensEventArgs args)
        {
            if (args.ContextItem == null)
                return;
            for (int index = 0; index < args.Models.Count; ++index)
            {
                SearchStringModel model = args.Models[index];
                if (model.Type.Equals("sxa") && this.ContainsToken(model))
                {
                    string str = model.Value.Replace(this.TokenPart, string.Empty).TrimStart('|');
                    Field field = args.ContextItem.Fields[str];
                    if (field != null)
                    {
                        this.Operation = model.Operation; //setting the operation given in the scope
                        args.Models.Insert(index, this.BuildModel(str, field.Value)); //pass the field value for filter
                        args.Models.Remove(model);
                    }
                }
            }
        }

        protected virtual SearchStringModel BuildModel(
          string replace,
          string fieldValue)
        {
            return new SearchStringModel("custom", FormattableString.Invariant(FormattableStringFactory.Create("{0}|{1}", (object)replace.ToLowerInvariant(), (object)fieldValue)))
            {
                Operation = this.Operation
            };
        }

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

Voici une courte démonstration où les champs Team et Buddy sont respectivement de type Texte sur une seule ligne et Droplink.

2 éléments personnalisés avec la même valeur dans le champ démo

Démo CustomItemsWithTheSameValueInField

ItemsWithIDsInFieldAsCurrentPage – Pour un type de champ complexe où un seul ID ou plusieurs ID sont sélectionnés.

using Sitecore.ContentSearch.Utilities;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.XA.Foundation.Search.Attributes;
using Sitecore.XA.Foundation.Search.Pipelines.ResolveSearchQueryTokens;
using Sitecore.XA.Foundation.SitecoreExtensions.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;

namespace CustomSXA.Foundation.Search.SearchQueryToken
{
    public class ItemsWithIDsInFieldAsCurrentPage : ResolveSearchQueryTokensProcessor
    {
        protected string TokenPart => nameof(ItemsWithIDsInFieldAsCurrentPage);

        protected string Operation { get; set; } = "should";

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

        public override void Process(ResolveSearchQueryTokensEventArgs args)
        {
            if (args.ContextItem == null)
                return;
            for (int index = 0; index < args.Models.Count; ++index)
            {
                SearchStringModel model = args.Models[index];
                if (model.Type.Is("sxa") && this.ContainsToken(model))
                {
                    string str = model.Value.Replace(this.TokenPart, string.Empty).TrimStart('|');
                    MultilistField field = (MultilistField)args.ContextItem.Fields[str];
                    if (field != null)
                    {
                        Item[] items = field.GetItems();
                        foreach (Item obj in ((IEnumerable<Item>)items).Reverse<Item>()) //loop through all the selected IDs
                        {
                            this.Operation = model.Operation; //setting the operation given in the scope
                            args.Models.Insert(index, this.BuildModel(str, Convert.ToString(obj.ID))); //pass the selected item ID for filter
                        }
                        if (items.Length >= 2)
                            index += items.Length - 1;
                        args.Models.Remove(model);
                    }
                }
            }
        }

        protected virtual SearchStringModel BuildModel(
          string replace,
          string fieldValue)
        {
            return new SearchStringModel("custom", FormattableString.Invariant(FormattableStringFactory.Create("{0}|{1}", (object)replace.ToLowerInvariant(), (object)fieldValue)))
            {
                Operation = this.Operation
            };
        }

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

Voici une courte démo où les champs Services et Compétences sont de type Multiliste.

3 Élémentsavecidsinfieldascurrentpage

ItemsWithIDsInFieldAsCurrentPage Démo

Corrigez les classes ci-dessus comme ci-dessous.

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <resolveSearchQueryTokens>
        <processor type="CustomSXA.Foundation.Search.SearchQueryToken.CustomItemsWithTheSameValueInField, CustomSXA.Foundation.Search" resolve="true" />
        <processor type="CustomSXA.Foundation.Search.SearchQueryToken.ItemsWithIDsInFieldAsCurrentPage, CustomSXA.Foundation.Search" resolve="true" />
      </resolveSearchQueryTokens>
    </pipelines>
  </sitecore>
</configuration>

Reportez-vous à la liste des packages NuGet à partir de ici.

Vérifiez dépôt pour l’implémentation ci-dessus dans le projet CustomSXA.Foundation.Search.

J’espère que cela t’aides.

Bonne portée des requêtes de recherche Sitecore 🙂






Source link