
Améliorer l’autocomplétion de Drupal pour une meilleure expérience utilisateur
Drupal propose nativement une fonctionnalité d’autocomplétion que l’on appelle autocomplete. L’utilisateur commence à taper du texte dans un champ et cette fonctionnalité suggère une liste de résultats qui correspondent au texte renseigné.
Cette fonctionnalité est très utile dans le processus éditorial pour pouvoir facilement faire référence à d’autres contenus du site depuis le contenu que l’on édite.
Toutefois, au fur et à mesure que le contenu de votre site s’étoffe, une difficulté peut apparaître : comment différencier des contenus qui ont le même titre pour savoir lequel référencer dans notre contenu éditorial ?
Nous vous proposons ici une solution pour améliorer l’affichage des données suggérées par l’autocomplete de Drupal et ainsi faciliter la vie de vos contributeurs.
Utilisation de l’autocomplete de Drupal dans sa version native
Commençons par présenter la fonctionnalité d’autocomplete telle qu’elle est proposée par Drupal, puis mettons en lumière la problématique rapidement rencontrée.
À quoi ça sert l’autocomplete ?
Comme nous l’avons dit en introduction, cette fonctionnalité est très utile pour (et très utilisée par les contributeurs) faire référence à d’autres contenus du site depuis un contenu source.
Imaginons par exemple un article de blog « article A » qui traite de la thématique « Drupal ». Il serait intéressant, sur la page de cet article, de suggérer à nos lecteurs d’autres articles, choisis arbitrairement, qui traitent eux aussi de la thématique « Drupal ».
Pour cela nous allons, dans l’édition de notre « article A » , faire référence à des articles « article B » et « article C ». Facile, jusqu’ici. Oui, mais ce que Drupal attend comme donnée dans notre champ de référencement, c’est l’identifiant interne unique associé à chaque contenu.
Si nous avons :
- article A : identifiant (ID) 123
- article B : (ID) 456
- article C : (ID) 789
Il faut donc que dans la page d’édition de notre « article A », nous renseignions les valeurs 456 et 789 pour que Drupal comprenne qu’il s’agit des contenus « article B » et « article C ».
On imagine difficilement des contributeurs aller rechercher ces valeurs numériques. Ce serait bien plus simple de renseigner le titre du contenu souhaité et que Drupal sache à quel identifiant de contenu nous faisons référence.
Bingo, c’est justement à ça que sert l’autocomplete !
Nos contributeurs n’ont qu’à renseigner du texte dans le champ de référencement et attendre que Drupal leur propose une liste de suggestions de titres de contenus.
Il n’y a plus qu’à cliquer sur la bonne suggestion pour qu’elle soit ajoutée au champ. Et Drupal de gérer tout seul l’association de l’identifiant unique à notre contenu.
Les options proposées par défaut par Drupal pour cette fonctionnalité permettent de jouer :
- sur le nombre de suggestions proposées,
- et sur le critère de recherche : à savoir, est-ce que la suggestion doit commencer par le texte renseigné ou bien est-ce que la suggestion doit contenir le texte renseigné ?
Les limites de l’autocomplete natif de Drupal
À la lecture du paragraphe précédent, nous pouvons nous dire que nos problèmes sont résolus.
Mais un problème peut vite se poser avec l’augmentation du nombre de contenus sur notre site : Comment faire pour différencier deux contenus qui auraient le même titre ? Ou bien comment savoir si une suggestion est un article ou une page ?
Amélioration de l’expérience utilisateur de l’autocomplete de Drupal
Maintenant que le problème est posé, voyons la solution. Pour facilement différencier nos suggestions, nous souhaiterions que les résultats retournés par l’autocomplete de Drupal nous donnent des informations supplémentaires telles que :
- le type de contenu,
- l’identifiant du contenu,
- la date de création et/ou modification,
- l’auteur du contenu.
Création de notre autocomplete amélioré
Dans les grandes lignes, voici ce que nous allons faire pour arriver à nos fins :
- créer un module personnalisé,
- surcharger le service
entity.autocomplete_matcher
de Drupal, - créer une nouvelle classe utilisée par ce service et qui hérite de la classe
EntityAutocompleteMatcher
, - utiliser notre nouvelle classe pour récupérer les données souhaitées,
- (optionnel) ajouter un peu de mise en forme via du code CSS pour une meilleure lisibilité.
Commençons par créer un nouveau module que nous appelons custom_autocomplete
.
> Redéclaration du service d’autocomplétion
Déclarons ensuite le service suivant dans le fichier custom_autocomplete.services.yml
:
services: |
Le service que nous déclarons s’appelle entity.autocomplete_matcher
. Ce service est également défini dans le core de Drupal dans le fichier core.services.yml
. Nous redéclarons donc le service.
Le fait de déclarer à nouveau le même nom de service est ce qui va nous permettre de surcharger l’autocomplete de Drupal. En effet, lorsque Drupal va vouloir utiliser le service, il va d’abord balayer les fichiers du core pour y trouver la déclaration du service, puis il va ensuite balayer les fichiers des modules et il va y retrouver une nouvelle déclaration de ce même service. C’est donc cette dernière déclaration qui fait foi.
> Création de la classe d’autocomplete
Créons maintenant la classe associée à la déclaration de notre service dans le fichier custom_autocomplete/src/Entity/CustomEntityAutocompleteMatcher.php
.
namespace Drupal\custom_autocomplete\Entity; |
Notre classe hérite de la classe EntityAutocompleteMatcher
qui est la classe associée à l’autocomplete par défaut de Drupal. Cela nous permettra de bénéficier de ses méthodes sans avoir à les réécrire.
>> Récupération des données : la méthode getMatches()
Nous allons maintenant, dans notre propre classe, surcharger la méthode getMatches()
de la classe EntityAutocompleteMatcher
et qui permet de chercher les suggestions et de les renvoyer à l’utilisateur.
/** |
Voyons en détail ce que fait cette méthode getMatches()
:
- BLOC 1 : Nous définissons nos options de tri des résultats. Si l’autocomplete par défaut renvoie les résultats par ID croissant, nous préférons ici avoir un affichage trié par ordre alphabétique.
- BLOC 2 : Si la variable
$string
(qui correspond à ce que l’utilisateur a renseigné dans son champ de recherche) existe, les critères du nombre de résultats à renvoyer et le type de recherche textuelle à effectuer sont ajoutés et la recherche est lancée. - BLOC 3 : Le code balaye chaque résultat de recherche pour en charger l’entité correspondante si elle existe. Si non, le résultat est ignoré, ne sera pas affiché à l’utilisateur et l’on passe au résultat suivant.
- BLOC 4 : Ce code est similaire à celui de la classe parent. Il définit la valeur qui sera réellement stockée dans le champ une fois que l’utilisateur aura choisi le résultat qu’il souhaite. Il est indispensable que l’identifiant du contenu soit mis entre parenthèses car le champ autocomplete de Drupal se base sur ce critère pour ensuite associer cet identifiant au champ (nous l’avons vu en introduction, la valeur attendue est « 123 » et non pas « article A »).
- BLOC 5 : Il s’agit de la partie réellement intéressante pour notre besoin. C’est dans ce bloc que nous venons construire le rendu pour l’affichage dans la liste de suggestions. Après avoir récupéré le nom du type de contenu auquel le résultat appartient, les données sont passées à notre méthode custom
getFormattedOutput()
qui va se charger de construire le rendu avec les données de l’entité souhaitées. - BLOC 6 : Chaque ligne de suggestion est insérée dans le tableau
$matches
qui est retourné pour affichage à l’utilisateur.
>> Mise en forme des données : la méthode getFormattedOutput()
Ajoutons la méthode getFormattedOutput()
à notre classe.
/** , |
Cette méthode récupère les données que l’on souhaite ajouter à chaque suggestion :
- le titre du contenu :
$entity→label()
- le nom du type de contenu :
$bundle_label
- l’identifiant unique du contenu :
$entity→id()
- la date de création ou modification du contenu :
$entity→getCreatedTime()
ou$entity→getChangedTime()
- l’auteur du contenu :
$entity→getOwner()→label()
Toutes ces données sont ensuite insérées dans du code HTML qui est renvoyé à la méthode getMatches()
.
Si nous reprenons notre exemple de contenus ayant le même titre, voici maintenant le rendu dans notre champ d’autocomplete.
Nous sommes maintenant en mesure de différencier facilement les suggestions retournées par l’autocomplete !
Amélioration de l’affichage de notre autocomplete
Nous disposons maintenant d’une fonctionnalité avec toutes les données nécessaires pour différencier nos contenus. Il est temps d’appliquer la touche finale en améliorant l’affichage des suggestions via un peu de CSS.
Pour ce faire, nous allons :
- Déclarer une librairie CSS dans un nouveau fichier
custom_autocomplete.libraries.yml
enhanced_link.autocomplete: |
- Attacher cette librairie à nos pages d’administration via le hook hook_page_attachments() que nous utilisons dans le fichier
custom_autocomplete.module
.
/** |
- Et enfin, définir un fichier CSS
enhanced_link.autocomplete.css
dans lequel nous définissons un minimum de style pour améliorer l’affichage.
/* Styles for the enhanced autocomplete link widget */ |
Et voici le rendu final de notre outil d’autocomplétion ! L’amélioration est flagrante par rapport à notre situation de départ. D’un coup d’oeil, nous savons qui a créé le contenu suggéré et quand, nous savons à quel type de contenu il appartient et enfin l’identifiant unique apparaît.
La structure finale de notre module, quant à elle, est la suivante :
Cet article vous montre qu’avec un minimum de fichiers et de code, il est possible d’améliorer notablement des fonctionnalités proposées par Drupal.
Via une logique simple qui consiste à surcharger un service déjà existant pour l’enrichir avec vos propres critères, vous disposez désormais d’un outil d’autocomplétion qui permettra à vos contributeurs d’utiliser plus facilement le back-office de Drupal.
Co-rédacteur : Vivien Barbeau - Développeur Drupal
Crédit photo : NanoStockk

