[🛠] Aligner les résultats de recherche sur les cartes de liste
✨ Résumé de GPT-5.5  
Journal du remplacement des cartes de recherche assemblées par chaînes JavaScript par une carte Liquid partagée, afin que date, catégories, vues et layout de l’overlay suivent les mêmes règles que les listes normales.
Les résultats de recherche avaient l’air anciens.
Sur l’accueil et les pages de catégories, les cartes d’articles étaient déjà plus cohérentes. Sous le titre, on voyait la date, les badges de catégorie et le nombre de vues dans la même ligne de métadonnées.
Mais en ouvrant la recherche, une ancienne UI apparaissait.
Elle affichait seulement le titre et l’extrait. On ne voyait pas immédiatement quand l’article avait été écrit. Il n’y avait ni catégorie ni vues. Le même article avait du contexte dans les listes normales, mais le perdait dans les résultats de recherche.
La cause était que les résultats de recherche étaient encore rendus par une chaîne HTML séparée en JavaScript.
Le rendu par chaînes JavaScript vieillissait la recherche
Lunr continue de gérer la recherche.
Pour un blog Jekyll statique, construire un store de recherche au moment du build puis l’interroger en JavaScript côté navigateur est logique.
Le problème était que JavaScript construisait aussi la carte du résultat.
Les listes normales étaient rendues par _includes/archive-single.html, tandis que les résultats de recherche étaient assemblés en chaînes dans assets/js/lunr/lunr-en.js.
La structure ressemblait Ă ceci :
Regular listing
-> Liquid include
-> archive__item
-> date, category, views
Search results
-> Lunr JS
-> hand-built HTML string
-> title and excerpt only
C’était la source du problème.
Si j’ajoutais des badges de catégorie aux listes normales, la recherche ne changeait pas. Si je modifiais la règle d’affichage de date, la recherche ne changeait pas. Si je retouchais les vues, la recherche restait identique.
La même carte d’article était maintenue à deux endroits.
J’ai séparé la carte d’article dans un include partagé
Au lieu de grossir le JavaScript de recherche, je lui ai fait produire moins de HTML.
J’ai ajouté des includes partagés.
_includes/archive-item-card.html
_includes/archive-item-meta-row.html
_includes/archive-item-categories.html
archive-item-card.html reçoit un document et rend la même structure que les listes d’archive existantes.
list__item
archive__item
archive__item-title
archive__item-meta-row
archive__item-excerpt
archive-item-meta-row.html regroupe date, vues et catégories sur une ligne. La date et les vues continuent d’utiliser page__meta.html, tandis que les catégories passent par archive-item-categories.html.
Ensuite, _includes/archive-single.html est devenu un wrapper mince.
{% include archive-item-card.html document=post type=include.type context="archive" %}
Les listes normales et les résultats de recherche utilisent maintenant le HTML généré par le même include.
J’ai mis le HTML complet de la carte dans le store Lunr
Lunr fait toujours la recherche.
Mais JavaScript ne construit plus le HTML de la carte.
Au build Jekyll, assets/js/lunr/lunr-store.js rend l’include de carte pour chaque document et place le résultat dans le champ html.
title
excerpt
categories
tags
lang
locale
html
url
teaser
Le JavaScript de recherche prend maintenant entry.html et l’insère.
Avant, il mélangeait liens de titre, image teaser, découpe d’extrait et assemblage de chaînes HTML.
var renderSearchResult = function (entry) {
return entry.html || '';
};
Le JS de recherche garde seulement la recherche, le filtrage par locale, l’affichage du nombre de résultats et l’insertion.
Les vues en recherche sont affichées, pas enregistrées
Il fallait décider si les résultats de recherche devaient aussi afficher les vues.
Au début, j’ai envisagé de les retirer. Les résultats pouvaient devenir chargés, et le DOM inséré dynamiquement demandait un traitement séparé.
Mais si la carte doit correspondre aux listes normales, retirer uniquement les vues est aussi étrange.
Les résultats de recherche affichent donc les vues. L’affichage et l’enregistrement restent séparés.
Search result exposure is not a visit.
The view count in search results is display-only.
Actual visit tracking belongs only to the currently opened page.
Les éléments de vues du blog ont data-page-view-path. La vraie cible de tracking est l’élément de la page courante avec data-page-view-track="true".
Les cartes de recherche ont seulement data-page-view-path; elles n’ont pas data-page-view-track="true".
Donc l’apparition d’un article dans la recherche n’incrémente pas ses vues.
Elle affiche seulement le nombre.
Je réapplique les vues aux résultats dynamiques
Les résultats de recherche ne sont pas dans le DOM au chargement initial.
Ils sont insérés après la saisie de l’utilisateur. Si le script de vues ne collecte les éléments qu’une fois au chargement, les vues dans les résultats ne seront jamais remplies.
J’ai donc aussi modifié assets/js/custom/visitor-stats.js.
Au lieu de fixer document.querySelectorAll("[data-page-view-path]") au début du fichier, il recherche ces éléments à chaque rendu des vues.
J’ai aussi mis en cache le payload analytics.
latestAnalyticsPayload
Après le rendu des résultats, le script de recherche déclenche hyuk:search-results-rendered.
Le script visitor stats écoute cet événement et, s’il a déjà un payload, réapplique les vues au nouveau DOM.
Il ne rappelle pas l’API.
Si chaque changement de saisie appelait l’API de vues, la recherche interférerait avec le compteur. Les résultats changent souvent, donc les requêtes réseau ne doivent pas suivre chaque touche.
Le flux devient :
Page load
-> receive analytics payload once
-> render views for existing listing/current page
Search results render
-> dispatch event
-> reuse cached payload for newly inserted DOM
Ainsi les résultats de recherche ne polluent pas le compteur.
Les métadonnées multilingues suivent chaque locale
Après le travail multilingue du blog, le site a des pages et collections par locale comme /en/, /ja/ et /zh-Hans/. La recherche ne doit pas mélanger les locales.
Le store de recherche contient lang et locale, et le HTML de la carte utilise la locale du document pour les labels. En anglais on voit Views, en japonais 閲覧数, et en français Vues.
Les catégories suivent la même règle.
Le préfixe de locale ne doit pas devenir un badge de catégorie. archive-item-categories.html ignore donc ce segment et affiche seulement les vraies catégories.
J’ai restauré la sidebar et une largeur plus grande dans l’overlay
Aligner la carte ne suffisait pas.
À l’ouverture de la recherche, la largeur des résultats restait trop étroite. Même avec le même HTML que les listes normales, l’espace à droite n’était pas utilisé.
Il y avait aussi un problème plus large : ouvrir la recherche faisait disparaître les catégories latérales.
L’overlay de recherche n’est pas posé au-dessus du corps existant. À l’ouverture, .initial-content est masqué et une zone séparée #site-search s’affiche.
La sidebar de la page normale disparaît donc aussi. Même avec une carte partagée, l’écran de recherche paraît séparé si le layout autour change.
J’ai donc inclus la sidebar dans _includes/search/search_form.html.
<div class="search-content__inner-wrap">
{% include sidebar.html %}
<div class="archive search-content__archive">
...
</div>
</div>
J’ai aussi enveloppé les résultats dans archive search-content__archive, pour qu’ils suivent le layout d’archive.
Puis j’ai retiré la règle CSS qui rétrécissait les cartes.
Minimal Mistakes avait cette règle pour la recherche :
.search-content .archive__item {
@include breakpoint($large) {
width: 75%;
}
@include breakpoint($x-large) {
width: 50%;
}
}
L’apparence ancienne ne venait donc pas seulement du HTML. Sur grand écran, la carte était réduite de moitié.
Dans le SCSS personnalisé, les cartes de recherche reprennent toute la largeur.
.search-content .archive__item {
width: 100%;
}
Il restait un autre détail.
L’archive normale réserve de l’espace à droite avec padding-inline-end pour la sidebar droite. L’overlay de recherche n’a pas cette sidebar. Garder ce padding rend les résultats trop étroits.
J’ai donc supprimé ce padding seulement pour l’archive de l’overlay.
.search-content .search-content__archive {
padding-inline-end: 0;
}
Les règles de rendu de carte restent partagées avec les listes normales ; seul le layout de l’overlay est ajusté pour la recherche.
J’ai vérifié desktop et mobile
J’ai lancé le build et les checks de syntaxe.
bundle exec jekyll build
node --check _site/assets/js/lunr/lunr-store.js
node --check _site/assets/js/lunr/lunr-en.js
node --check _site/assets/js/custom/visitor-stats.js
Le store généré contient page__views et data-page-view-path.
Le HTML de carte de recherche ne contient pas data-page-view-track="true", ce qui évite de mélanger exposition dans la recherche et tracking de visite.
J’ai ensuite ouvert la recherche dans plusieurs pages locale et testé des requêtes comme :
References
Keymory
Daily review
Les cartes affichaient date, catégorie et vues dans la même ligne de métadonnées que les listes normales. Les labels suivaient chaque locale : Views, 閲覧数, Vues et les autres.
Dans les résultats, data-page-view-track="true" était absent. Sur les pages d’articles, l’élément de tracking de la page courante apparaissait toujours une seule fois.
L’overlay de recherche avait de nouveau la sidebar. À 1280px de large sur desktop, la sidebar avait 22 éléments et la carte de résultat atteignait environ 974px de largeur.
À 390px sur mobile, la sidebar se plaçait au-dessus et la carte utilisait 345px pour le titre, les métadonnées et l’extrait.
La console du navigateur n’affichait aucune erreur.
Laisser un commentaire