| Version actuelle | 1.39.0 (voir aussi style.css et package.json) |
| Licence | EUPL-1.2 |
| WordPress minimum | 6.6 |
| PHP minimum | 8.0 |
| Node.js minimum | 18 (npm 8+) |
Thème WordPress Full Site Editing pour sites vitrines, portfolios et agences : templates FSE, blocs G2RD, options en React et qualité de code suivie en CI.
G2RD Theme fournit une base FSE (templates, parties, variations) et une collection de blocs Gutenberg orientés métier (SEO, GEO, mise en page, contenus dynamiques). Le dépôt inclut scripts de build, tests ciblés et workflow de release (ZIP + GitHub Releases).
- Agences / freelances qui livrent des sites WordPress FSE avec des blocs sur mesure.
- Clients finaux qui veulent éditer le site dans l’éditeur sans toucher au code (après formation légère).
- Développeurs qui clonent le repo pour compiler les blocs, lancer les audits et contribuer.
- FSE :
templates/,parts/,patterns/,styles/,theme.json+ composition viatheme-settings.json/theme-styles.json. - Blocs : dossier
blocks/(workspaces npm), manifest généré, build via@wordpress/scripts. - PHP : classes sous
classes/(autoload Composer),functions.php, CPT optionnels, intégrations documentées dans le code. - Qualité : PHPCS (WordPress + sécurité + compat PHP), tests JS blocs, Smart CI sur
main/develop. - Documentation :
docs/— guides client (installation, licence, blocs, SEO, GEO…) ; côté technique : Licences, Standard blocs, CLAUDE.md pour les conventions du repo.
- Blocs G2RD (
g2rd/*) : fonctionnalités avancées ; sans licence active, le thème reste utilisable mais l’insertion de nouveaux blocs premium peut être restreinte (voir comportement dansclass-block-editor-autoload.phpet docs/licensing.md). - Mises à jour automatiques depuis GitHub : liées à une licence valide (FluentCart côté boutique G2RD).
- SureCart : conservé uniquement pour compatibilité de certains contenus (ex. produits), pas pour les nouvelles licences — détail dans docs/licensing.md.
git clone https://github.com/SebG2RD/g2rd-theme.git
cd g2rd-theme
npm install
composer install- PHP 8.0+, WordPress 6.6+, Node 18+.
- Pour un site local : activer le thème comme tout thème WordPress (dossier dans
wp-content/themes/ou ZIP fourni par une release).
| Action | Commande / déclencheur |
|---|---|
| Compiler tous les blocs | npm run build |
| Watch développement | npm run start |
| Un bloc (exemple) | npm run build:faq |
| Audits npm / blocs | npm run audit:blocks, npm run test:blocks |
| Qualité PHP | composer run phpcs, composer run phpstan, composer run phpunit |
Release : push d’un tag v* (ex. v1.6.9.5) déclenche .github/workflows/release.yml — build, npm audit, composer audit, vérification des versions, ZIP propre, test d’activation WordPress, GitHub Release + notification g2rd.fr.
Alignement des versions : style.css, package.json, readme.txt (Stable tag), composer.json (extra.g2rd_theme_version) — script tools/verify-release-version.sh.
Historique des versions : changelog.txt et Releases GitHub (notes détaillées par version).
g2rd-theme/
├── assets/ # CSS/JS compilés, images, polices
├── blocks/ # Blocs Gutenberg (un dossier par bloc + workspaces)
├── classes/ # Logique PHP (FSE, options, licence, CPT, etc.)
├── includes/ # Fichiers inclus (ex. licence)
├── parts/ templates/ patterns/ styles/ # FSE
├── theme.json # Base FSE (complétée à l’exécution)
├── theme-settings.json / theme-styles.json
├── functions.php
└── tools/ # Scripts de vérification (release, versions, ZIP)
- Point d’entrée :
functions.php+ autoload Composer. - Détails techniques et conventions : CLAUDE.md.
- Poursuivre la documentation par bloc et l’audit
docs/blocks/README.md. - Modularisation progressive (thème “design” vs extensions “suite / blocs / licence”) pour isoler les risques.
- Renforcer les tests (PHP + éditeur) sur les blocs les plus utilisés.
- Suivre les évolutions Gutenberg / WordPress et ajuster dépréciations +
theme.json.
- Documentation : dossier
docs/et ce README. - Bugs / évolutions : Issues GitHub.
- Clients : espace G2RD (FluentCart) pour licence et téléchargements.
- Développement : Sebastien GERARD — g2rd.fr
- Basé sur WordPress FSE et l’écosystème @wordpress/scripts.
- Variations de styles depuis le thème enfant :
composeThemeJson()charge désormais<enfant>/styles/*.jsonen plus de celles du parent. Les fichiers sont indexés par nom, donc une variation de l'enfant remplace celle du parent en gardant sa place dans le sélecteur. Une variation propre à un client vit ainsi dans son thème enfant et survit aux mises à jour du parent, qui remplace tout le dossier du thème. La clé de cache intègre lesmtimede ces fichiers : modifier une variation enfant invalide le transient sans purge manuelle. Sans thème enfant, le comportement est inchangé. - Variation Moovéa — carte en héros éclaircie : fond de canevas et de conteneur en
blush, filtre de tuiles adouci, voile dégradé horizontal sur grand écran et vertical sous 781 px.
- Variation de styles Moovéa à jour : token
terracotta-vif, carte en héros (filtre de teinte, marqueur animé, panneau superposé), bandeau défilant, habillage de la fenêtre modale, survol des cartes d'offres, bloc citations et calage du héros sur la hauteur d'en-tête via--mv-header-h. Cette variation était déjà déployée manuellement sur le site concerné : l'archive 1.38.0 en embarquait encore la version précédente et l'aurait écrasée à la mise à jour.
- Serveur MCP extensible : nouveau filtre
g2rd_mcp_abilities— un plugin peut enregistrer ses propres outils MCP sans modification du thème. Les noms d'outils du cœur sont protégés, une entrée sans callback appelable est rejetée et les portées omises retombent surread_only/manage_options. Le chemin d'exécution des outils existants est inchangé : aucun d'eux ne déclare de callback. - Grille filtrable — couleur de bordure des boutons : réglable depuis le panneau Couleur, au même endroit que la couleur des titres et du texte. Le premier choix amorce une bordure de 1px en trait plein si aucune largeur n'est définie, pour que le trait apparaisse immédiatement.
- Sécurité des dépendances :
smol-tomlépinglé en 1.8.0 (avis high : déni de service via document TOML malformé, chaîne@wordpress/scripts→markdownlint-cli). - Documentation : section « Étendre le serveur MCP » dans le guide, conception et limites détaillées dans
docs/internal/mcp-extending-tools.md.
- Sécurité MCP :
tools/callauthentifie le token avant de signaler un outil inconnu — plus d'énumération des outils sans token valide. - Bridge MCP : à la fermeture de stdin, le bridge attend la fin des requêtes en cours avant de quitter (réponses perdues en ligne de commande).
- Docs : nouveau chemin du dossier de développement et rappel
npm link.
- Fix avis Google (bloc Témoignage) : rendu mobile des dispositions marquee et carrousel : la largeur des cartes était calculée en JS en divisant le conteneur par le nombre de colonnes configuré (ex. 3), quel que soit l'écran — sur téléphone chaque carte tombait à la largeur du mot le plus long (un mot par ligne). Le nombre de colonnes est désormais borné par la largeur réelle de la piste : 1 sous 560 px, 2 au plus sous 900 px, le réglage du bloc au-delà, avec un plancher de 240 px par carte.
- Recalcul au redimensionnement (rotation du téléphone, fenêtre redimensionnée) via
ResizeObserverthrottlé parrequestAnimationFrame, mesure faite sur la piste réelle une fois dans le DOM (tient compte du padding des flèches du carrousel). box-sizing: border-boxsur la carte d'avis : le padding s'ajoutait à la largeur calculée et la carte débordait du conteneur de 2 × 1.4rem dès qu'elle occupait toute la largeur. Aucune modification de page nécessaire.
- Fix RGAA : les images gardent leur texte alternatif : la règle « image décorative » de
inc/rgaa-accessibility.phplisait une clé méta inexistante (_wp_alt_text) et forçait doncalt=""+role="presentation"sur toutes les images, y compris celles dont l'alt était renseigné en médiathèque (RGAA 1.1 / 1.2). Elle lit désormais la vraie clé WordPress_wp_attachment_image_altet respecte unaltfourni par l'appelant (ex. image mise en avant liée, où le cœur passe le titre de l'article). Seules les images sans aucun alt restent marquées décoratives.
- Fix page de connexion : le bouton « Se connecter » reste visible quoi qu'il arrive : WordPress core applique
overflow: hiddenet une bordure sur.login form. Enfant flex de la colonne#login, le formulaire était le seul élément à rétrécir quand la hauteur manquait (zoom navigateur, petit écran) et son bas — le bouton de connexion — était rogné. Le formulaire ne rétrécit plus (flex-shrink: 0,overflow: visible), la bordure grise core est supprimée et aucun enfant du panneau ne peut être compressé. - Centrage vertical par marges auto au lieu de
justify-content: center: lorsque le contenu dépasse la fenêtre, la page défile au lieu de couper le haut ou le bas du panneau. - Écrans peu hauts (
max-height: 800px) : espacements verticaux et hauteur du logo resserrés pour garder le bouton à l'écran sans défilement dans la plupart des cas. - Dépendances : correction de 6 alertes Dependabot (
fast-uri,postcss-selector-parser,browserslist,qs) viaoverridesracine.
- La sélection de catégories restreint enfin la grille, pas seulement le filtre : en 1.37.0, cocher une catégorie ne limitait que les choix du menu déroulant — tous les produits restaient affichés. L'endpoint
/g2rd/v1/postsaccepte désormais un paramètreterms(liste d'IDs, validée par/^\d+(,\d+)*$/, dédoublonnée et plafonnée à 50) et le frontend l'envoie dès que le mode est « Sélection ». Le choix du visiteur dans le filtre reste prioritaire, à l'intérieur du périmètre retenu. - L'aperçu de l'éditeur applique la même restriction que le front, pour ne pas rouvrir d'écart de rendu entre les deux.
- Entités HTML des noms de catégories : l'API REST des termes renvoie le nom encodé, si bien qu'une catégorie « Cellules & Essaims » s'affichait « Cellules & Essaims » dans l'éditeur comme dans le filtre. Décodage via
DOMParsersur un document détaché — aucune valeur brute ne transite parinnerHTML. - Aucune reconfiguration nécessaire :
save.jsest inchangé, ledata-termsdéjà enregistré par la 1.37.0 est simplement exploité.
- Grille filtrable : choisir les catégories proposées au visiteur : quand le filtre par taxonomie est activé, un contrôle « Catégories proposées » offre Toutes ou Sélection. En mode Sélection, les catégories de la taxonomie s'affichent en cases à cocher, celles sans contenu étant signalées
(vide). Vaut sans code spécifique pour les articles (category) comme pour les produits WooCommerce (product_cat) : la liste suit la taxonomie choisie. Cocher zéro catégorie revient à toutes les afficher plutôt qu'à vider le filtre. - Le filtre par catégories ne fonctionnait pas sur les articles : le frontend interrogeait
wp/v2/{slug}avec le slug de la taxonomie alors que la route REST utilise sonrest_base— pourcategory, c'estwp/v2/categories. La requête partait en 404, avalée par uncatchsilencieux, et la liste déroulante restait vide sans le moindre message. Lerest_baseest désormais résolu via/wp/v2/taxonomies/{slug}, avec repli sur le slug. - Aucun contenu existant invalidé : les attributs
data-term-modeetdata-termsne sont sérialisés que si le mode est « Sélection » et qu'au moins une catégorie est cochée. Les grilles déjà en base produisent exactement le même HTML qu'avant — pas de dépréciation nécessaire. /g2rd/v1/content-typesexpose maintenant lerest_basede chaque taxonomie, en plus de son slug et de son libellé.
- La barre de progression rendait une couleur en back-office et une autre sur le front :
render.phppose--wrb-progress-bar-coloret--wrb-progress-track-colorsur le conteneur, alors que l'éditeur forçaitbackgroundColoren style inline sur la piste et le remplissage, plus unstrokeen dur sur les cercles SVG — que le front, lui, ne pose pas. Deux mécanismes pour un même rendu : toute couleur venant d'ailleurs dans la cascade (variation de styles, thème enfant) s'appliquait au front et jamais à l'éditeur. L'éditeur écrit désormais les deux mêmes variables sur le conteneur et ne force plus rien en aval. - Variation « L'Aixoise » : contraste de la palette revu — slug
accent-fonce(#634B77) ajouté pour les liens en lecture,mutedassombri à #5F5566, liens portés suraccenthover. Fraunces remplace Bodoni Moda comme intérim de Retrofia. - Variation « Moovéa » : mise en forme des pages légales (
.mv-legal) — titres, filets de séparation et rythme vertical.
- Le compte à rebours rend enfin la même chose dans l'éditeur et sur le front :
edit.jsne posait ni la classeg2rd-countdownni les variables CSS sur son conteneur — la feuille du bloc ne s'appliquait donc pas du tout dans l'éditeur, qui redessinait tout en style inline. Les deux contextes partagent désormais les mêmes classes, les mêmes variables et la même feuille. - Les réglages du compte à rebours agissent sur le front :
countdown.cssécrivait des valeurs en dur et ignorait les variables que son propresave()posait. Espacement, marge intérieure, couleur de fond des pastilles, arrondi, taille de la valeur et du libellé, et jusqu'à la vitesse d'animation, ne produisaient aucun effet en dehors de l'éditeur. - Le titre du compte à rebours repasse au-dessus des pastilles : le conteneur était en
flex-direction: row, où.countdown-container{width:100%}écrasait le<h2>à gauche. Les marges héritées qui s'ajoutaient augapsont retirées. - CSS des deux blocs en 100 % tokens : plus une seule couleur hexadécimale ni une seule taille en dur — chaque valeur historique devient le repli d'un
var()adossé à un token dutheme.json. Un site qui n'a jamais touché aux réglages rend à l'identique. La couleur du texte revient autheme.json, et l'ombre des pastilles est neutralisable depuis une variation viasettings.custom.countdown.itemShadow, sans!important. - L'alignement du compteur n'est plus ignoré :
style.cssforçaitjustify-content: centerettext-align: centerplus bas dans la cascade que letext-alignposé parsave(). Le rendu suit maintenant le contrôle d'alignement, y compris pour les dispositions avec icône latérale. - Feuille du compte à rebours mise en file une seule fois :
ScriptsManager::enqueue_g2rd_countdown_css()doublonnait le"style"dublock.json, avec deux handles pour le même fichier dans le<head>. - Variation « L'Aixoise » allégée sur
g2rd/countdown: le conteneur ne porte plus ni fond blanc, ni filet, ni rayon, ni ombre — une carte dans une carte, hors charte sur une section crème. Le décor revient aux pastilles. - Pattern « Section Hero Animé » réparé : il posait
g2rd/counteravec des attributs disparus et en balise auto-fermante alors que le bloc a unsave()statique — trois blocs en « contenu invalide » à l'insertion.
- Trois blocs qui comblent des manques du thème :
g2rd/timeline(suite ordonnée, verticale pour un programme heure par heure, horizontale pour un processus — sortie en<ol>avec les heures en<time datetime>) ;g2rd/pricing-tiers(grille tarifaire dont le palier actif se déduit de la date du jour, les paliers écoulés grisés et barrés, un bandeau annonçant la bascule) ;g2rd/route-map(carte de parcours GPX analysée côté serveur et mise en cache, distance, dénivelé par hystérésis, profil altimétrique en SVG, tracé Leaflet auto-hébergé sur fond OpenStreetMap — sans clé d'API ni cookie tiers). - Les trois blocs suivent la variation de styles active, pas une charte figée : chaque
var()se rabat en cascade sur un token garanti partheme-settings.json, si bien que le rendu reste correct sous les neuf variations et pas seulement sous celle pour laquelle les blocs avaient été écrits. Aucune valeur hexadécimale en dur, y compris pour la couleur du tracé Leaflet, queview.jslit sur les variables CSS. - Variation de styles « L'Aixoise » : charte Burnt Coral / Purple Heart / Egret, titres Retrofia, texte Montserrat. Les slugs du thème parent sont conservés et remappés — les variations de blocs (
is-style-card,is-style-section-dark,is-style-action…) adoptent la charte sans une ligne de CSS supplémentaire. Comme toute variation, elle n'a aucun effet tant qu'elle n'est pas sélectionnée. - Le message d'assistance ne passe plus devant la page d'options : sans marqueur
wp-header-end, WordPress déplace les notices derrière le premier<h1>de.wrap— celui de l'en-tête collant de l'application React, enz-index: 100. Les notices débordaient de cet en-tête et recouvraient la navigation. Le marqueur les ancre au-dessus de l'interface. - Contraste corrigé dans « L'Aixoise » (RGAA 3.2) : les liens de
is-style-card-actionplafonnaient à 2,2:1, le corail sur le dégradé violet. Ils passent en blanc souligné, soit 5,6:1 au point le plus défavorable du dégradé. - Fuseau horaire respecté dans la grille tarifaire : les dates de palier sont interprétées dans le fuseau du site. Un site réglé sur un fuseau négatif affichait la veille de la date saisie.
- Transients du
theme.jsonpurgés au changement de thème : la purge n'était branchée que sousWP_DEBUG, les lignes restaient en base jusqu'à expiration. La purge ciblée ne vide pas l'object cache global, contrairement au vidage complet réservé au développement. - Sécurité —
extract-zipretiré de l'arbre de dépendances (CVE-2026-56876, CVSS 8.1) : extraction d'archive sans validation des liens symboliques. Le paquet est abandonné et aucun correctif ne viendra de l'amont ;@puppeteer/browsers3.x l'ayant remplacé parmodern-tar, un override supprime la branche entière — 44 paquets en moins. Dépendance de développement, jamais livrée dans le ZIP : les sites n'étaient pas exposés. - Deux pièges de livraison levés : le classmap Composer ignorait la nouvelle classe
RouteMapSupport(erreur fatale sur chaque page une fois livrée), etassets/vendor/leaflet/tombait sous la règle d'exclusionvendordu ZIP de production — Leaflet n'aurait jamais été embarqué.
- Quatre pages Moovéa en patterns : Le Pilates Reformer (page pilier — mal de dos, post-partum, ménopause), Tarifs (offre Founders et grille complète), Inès (récit de la fondatrice) et Contact (formulaire Fluent Forms, créneaux, accès). L'accueil devient une porte d'entrée plutôt qu'une page unique : trois boutons y renvoient vers la page pilier, la grille tarifaire et la page fondatrice, et le pied de page reçoit un bloc de navigation vers les cinq pages.
- Le défilement reste arrêtable au clavier, bouton masqué ou non (RGAA 13.8) : la pause au survol est hors de portée du clavier, si bien qu'un internaute qui tabulait n'avait aucun moyen d'interrompre un contenu en mouvement quand le bouton était masqué. Le bouton existe désormais dans tous les cas, escamoté tant qu'il n'a pas le focus — technique du lien d'évitement, élément conservé dans l'ordre de tabulation. Le rendu par défaut est inchangé.
- Formulaires Fluent Forms habillés dans la variation Moovéa : les champs, libellés, messages d'erreur et boutons suivent désormais les tokens de la charte, en version pleine page comme en version compacte dans la barre fondatrices — laquelle reçoit son formulaire réel en remplacement de l'emplacement vide.
- Correction du pied de page Moovéa : l'année du copyright repasse par le block binding
g2rd/current-year. Un placeholder{{annee}}s'y était glissé, qu'aucun code du thème ne remplace — il se serait affiché tel quel en production. - Adresse du studio complétée : « 60 place de la République » sur l'accueil, dans la FAQ et dans le pied de page.
- Un style de focus visible, garanti par le thème (RGAA 10.2) : aucune règle
:focusn'existait, ni dansstyle.cssni danstheme.json. On s'en remettait à l'anneau natif du navigateur, invisible sur les fonds sombres de la palette — un focus présent mais indiscernable ne satisfait pas le critère, qui demande un focus visible. L'anneau est bicolore parce que la mesure l'impose : sur les treize couleurs de la palette, aucune teinte unique n'atteint le seuil de 3:1 sur toutes, alors que navy et blanc, complémentaires, les couvrent toutes les treize. Le halo clair porte la visibilité sur fond sombre, l'anneau sombre sur fond clair. Les deux teintes passent par des variables CSS, remplaçables par une charte après vérification de ses propres contrastes. - Le panneau d'accessibilité retrouve son anneau : quatre règles
:focus-visibley annulaient le contour pour le remplacer par une teinte à 8–12 % d'opacité, neutralisant la règle globale dans le composant même censé aider. - Le bloc Carte restitue tous ses lieux (RGAA 1.1) : seul le premier marqueur était décrit, si bien qu'une carte de plusieurs agences n'en annonçait qu'une. Le titre d'un marqueur étant vide par défaut, la description retombait par ailleurs sur un texte générique sans aucune information de localisation dès que l'auteur n'en saisissait pas. Les marqueurs nommés sont désormais listés avec leur description, le repli indique franchement qu'aucun lieu n'a été nommé, et la région reçoit un nom accessible —
aria-describedbyfournit une description, pas un nom.
- Bande blanche sous l'en-tête, corrigée. Le lien d'accès rapide introduit en 1.33.0 posait sa cible dans une balise ajoutée en tête du contenu principal. Ce simple élément suffisait à décaler tout le reste : WordPress applique
margin-block-startà tout enfant d'une mise en page contrainte qui n'est pas le premier, et le contenu réel, devenu deuxième, héritait de cette marge. Le fait que l'élément soit invisible et hors flux n'y changeait rien — la règle compte les frères, pas les boîtes. La cible est désormais portée par le contenu principal lui-même, sans élément ajouté : plus de marge, sur tous les gabarits et toutes les mises en page. - Les niveaux de gris ne font plus disparaître le panneau d'accessibilité. Activer ce mode envoyait le bouton flottant tout en bas du document, hors de l'écran, où il restait même après défilement : le panneau devenait impossible à rouvrir, donc le mode impossible à désactiver. En cause, un
filterCSS posé surhtmletbody— un filtre fait de l'élément qui le porte le bloc conteneur de ses descendants enposition: fixed, si bien que le widget se plaçait par rapport au document entier plutôt qu'à la fenêtre. Le filtre porte désormais sur les enfants directs dubody. Le widget reste en couleur, étant la commande qui permet de sortir du mode. - Le bouton du panneau annonce ce qu'il commande :
aria-expandedsignalait qu'un contenu était déployé sans indiquer lequel ;aria-controlscomplète l'information. - PHP_CodeSniffer 3.13.6 — injection de commande via un nom de fichier dans les rapports Gitblame, Hgblame et Svnblame. Dépendance de développement, absente du ZIP de production, et aucun de ces rapports n'est employé : l'exposition côté sites était nulle.
- Compte à rebours — le temps affiché était faux dès qu'une unité était masquée. Les années et les mois étaient retranchés qu'on les affiche ou non : une échéance à deux ans réglée sur jours et heures montrait « 0 jour, 2 heures », les 730 jours ayant été absorbés par des unités invisibles. La plus grande unité affichée porte désormais tout ce qui la dépasse — la même échéance affiche « 733 jours, 4 heures ».
- La fenêtre modale s'annonce comme un dialogue. Elle retenait déjà le clavier, déplaçait le focus à l'ouverture et le rendait à la fermeture, mais ne portait ni
role="dialog"niaria-modal: un lecteur d'écran laissait donc parcourir la page située derrière alors que le clavier y était retenu. Un nom de repli est posé lorsque la modale ne contient aucun titre. - Trois avis de sécurité élevés sur
js-yaml, atteint par trois chemins de@wordpress/scripts, corrigés par unoverrideen version patch plutôt qu'une montée majeure de la chaîne de build.
- Lien d'accès rapide au contenu (RGAA 12.5) : aucune page n'en proposait. Il est désormais posé en premier élément focusable de toutes les pages, quelle que soit la configuration du site. Sa cible est une ancre dédiée insérée dans le contenu principal, et non un identifiant posé sur celui-ci : un ancrage défini par l'auteur aurait sinon fait pointer le lien vers une cible absente.
- Sommaire (12.3) : activer une entrée déplaçait la vue sans déplacer le focus, si bien qu'au clavier la tabulation suivante repartait du sommaire et non de la section atteinte — le lien paraissait sans effet. Le bloc est aussi identifié comme repère de navigation et nommé.
- Compte à rebours : les chiffres se réécrivaient chaque seconde sans aucun balisage, sans qu'un lecteur d'écran ne signale jamais le changement. Le compteur visuel est masqué aux technologies d'assistance et doublé d'un résumé annoncé au rythme de la minute, jamais de la seconde.
- Barre de progression (1.1) : sa valeur était intégralement perdue — la piste était marquée décorative et le pourcentage masqué. Les deux variantes, barre et cercle, l'exposent désormais.
- Carrousel (7.3) : manœuvrable aux flèches, en plus des boutons.
- Contrastes signalés, jamais modifiés (10.6) : l'administration avertit lorsque des couleurs associées dans le balisage passent sous le seuil AA. Aucune palette n'est touchée — une charte est une décision de marque. Le contrôle se limite aux couples réellement employés : sur la palette du thème, 53 combinaisons théoriques échouent alors qu'aucune n'est effectivement posée.
- Titres (9.1, 9.2) : les chiffres d'un hero (« 150+ », « 98% ») étaient balisés en titres et polluaient le sommaire lu par un lecteur d'écran ; un
h3précédait le premierh2. - Aucun
save.jsn'est modifié : rien n'invalide le contenu déjà publié.
- Moovéa : pied de page et en-tête retravaillés (logo image à la place du logo de site, colophon), pattern d'accueil et variation de style affinés.
- Nouvelle source de liaison
g2rd/current-year: le pied de page portait© {{annee}}, un marqueur qu'aucun mécanisme du thème ne traitait — il se serait affiché tel quel sur le site. La mention de copyright lit désormais l'année réelle.wp_date()est utilisé plutôt quedate()pour suivre le fuseau configuré dans WordPress : sur un serveur en UTC, un site en heure française aurait affiché l'année précédente pendant les deux premières heures du 1er janvier. .phpunit.cache/ignoré : le répertoire de cache de PHPUnit 10 était suivi par Git, si bien que chaque exécution des tests laissait un fichier modifié dans l'arbre de travail. Seul.phpunit.result.cache, son équivalent des versions antérieures, l'était.
- Projet Moovéa : variation de style
styles/moovea.json(palette bordeaux / crème / vert d'eau, trois familles typographiques), patternmoovea-accueilet trois parties de gabarit — en-tête, pied de page et bandeau fondatrices. - Parties de gabarit déclarées dans
theme.jsonavec leur zone et leur titre. Sans cette déclaration, l'éditeur de site les rangeait en « non catégorisé » et les affichait sous leur nom de fichier, au lieu de les proposer aux emplacements d'en-tête et de pied de page.
- Page d'options entièrement reprise : les 178 attributs
styleen ligne dispersés dans les dix onglets réinventaient les mêmes encarts, badges et blocs de code avec 41 couleurs codées en dur. Un même « Actif » pouvait être vert#166534dans les tokens et#00a32adans les licences, et changer la palette imposait de repasser sur chaque fichier. Il en reste trois, sur les pastilles de couleur choisies par l'utilisateur, où la valeur est la donnée et non du style. - Aucun changement de comportement : ni logique, ni appel REST, ni état React n'a bougé. Seule la présentation passe par le socle de tokens, qui existait déjà mais était contourné.
- Quatre contrastes sous le seuil AA corrigés — étiquette « info » (4,3:1), étiquette neutre (4,1:1), compteur de file (4,3:1) et bouton Confirmer (3,6:1) montent entre 5,0 et 7,8:1. Les couleurs vives servent désormais aux bordures et aux icônes, jamais de support à du texte.
- L'aperçu de la page de connexion ne peut plus mentir : ses valeurs par défaut étaient recopiées dans deux fichiers, si bien qu'un défaut modifié d'un seul côté faisait afficher à l'aperçu autre chose que ce que verrait réellement l'utilisateur en se connectant. Une table partagée les aligne,
LoginCustomizer::DEFAULTSrestant l'autorité à l'enregistrement. - Éléments jamais stylés depuis l'origine : la carte de licence et les grilles du module IA portaient des classes sans aucune règle correspondante — la « carte » n'était qu'une pile de blocs et
is-activene changeait rien. Elles sont habillées. - Formulaires utilisables sur petit écran : les grilles à quatre colonnes tombent en une seule sous 782 px, le point de rupture des écrans admin WordPress, où elles écrasaient les champs jusqu'à les rendre inexploitables.
- Un statut absent n'est plus réécrit :
g2rd_update-woo-productrepassait le produit en brouillon dès que le statut n'était pas fourni. La cléstatusétait toujours créée avecdraftpar défaut, puis testée avecisset()— donc toujours vraie. Une mise à jour ne portant que sur le prix retirait le produit de la boutique, sans que rien ne le signale. Le champ n'est désormais écrit que s'il a été explicitement fourni ;draftreste le défaut à la création seulement. - Vérification des outils voisins :
g2rd_update-postetg2rd_update-woo-variationtestaient déjà la présence de l'argument et n'étaient pas concernés.g2rd_update-woo-productétait le seul touché. - Résumé d'e-mail sincère : le récapitulatif affiche « (inchangé) » au lieu d'un
drafttrompeur. Sans cela, l'administrateur approuvait une dépublication en croyant valider un changement de prix — le garde-fou de confirmation présentait une intention qui n'était pas la sienne. - Fenêtre de confirmation portée de 15 à 60 minutes : quinze minutes doivent couvrir la latence de distribution du courrier, la lecture du payload et la décision — et l'administrateur n'est pas nécessairement devant sa boîte. Une demande expirée oblige l'agent à tout resoumettre, ce qui décourage l'usage même du garde-fou. Soixante minutes reste borné : un lien de confirmation n'a pas vocation à valoir une journée.
- Tests : 3 nouveaux sur le statut. Suite complète à 190 tests / 1 195 assertions.
- MCP — pilotage des variations WooCommerce : cinq nouveaux outils,
g2rd_list-woo-variations,g2rd_get-woo-variation,g2rd_create-woo-variation,g2rd_update-woo-variationetg2rd_delete-woo-variation. Les outils existants sont inchangés. - Le problème corrigé : sur un produit variable, prix, promo et stock vivent sur les variations et non sur le parent.
g2rd_get-woo-productrenvoyait donc des champs vides et unpriceréduit au plancher de la fourchette. Impossible de savoir quels formats existaient, à quel prix, ni d'en corriger ou d'en retirer un — au point qu'une fiche annonçant « pot de 500 g uniquement, 12 € » cohabitait avec une variation de 250 g toujours achetable à 7 €. - Attributs lisibles : la sortie donne « 500 g » et pas seulement
pa_poids: 500-g, tout en conservant le slug pour réécrire. - Stock à deux niveaux explicite : un champ
stock_sourceindique si la quantité vient de la variation, est héritée du parent, ou n'est pas gérée. Unstock_quantitynul seul était ambigu. - Prix en chaînes décimales, contrat strictement identique à
g2rd_update-woo-product— la méthode de normalisation est partagée plutôt que dupliquée, pour qu'elle ne puisse pas diverger. Aucune conversion en nombre flottant :"7.10"et"7.1"restent distincts à l'écriture. - Prix promotionnel vérifié contre le prix normal effectif : celui fourni s'il l'est, sinon celui déjà en base. Sans cela, un prix promo supérieur au prix existant passait et WooCommerce l'ignorait en silence.
- Caches invalidés après chaque écriture : transients du produit parent, recalcul de la fourchette de prix, puis purge du cache page. Sans quoi la boutique continue d'afficher l'ancien prix plancher, ce qui se signale comme un bug sans en être un.
- Garde-fous : la suppression de la dernière variation d'un produit variable est refusée avec la marche à suivre — un produit variable sans variation n'est plus achetable ; il ne reste qu'une variation, c'est signalé sans bloquer. La création refuse un attribut non déclaré sur le parent ou une combinaison déjà existante. Sur un produit simple, la liste renvoie un message explicite plutôt qu'un tableau vide.
- Tests : 11 nouveaux. Suite complète à 185 tests / 1 186 assertions.
- E-mail de confirmation MCP lisible : le corps affichait le payload en JSON brut, illisible pour qui n'est pas développeur — or c'est le seul point de contrôle humain avant l'exécution d'une commande distante. L'e-mail présente désormais deux sections : « Ce qui va être fait », un résumé en français champ par champ (titre, statut, catégories, prix…), et « Contenu exact qui sera écrit », le payload reproduit fidèlement.
- Fidélité garantie : le bloc de contenu exact ne subit aucune mise en forme, et l'e-mail est désormais envoyé avec un en-tête
Content-Type: text/plainexplicite. Sans cet en-tête, un plugin SMTP ou une passerelle pouvait interpréter le corps comme du HTML ou du Markdown et réécrire les URL et les balises du payload — l'e-mail affichait alors autre chose que ce qui allait réellement être écrit. - Gros contenus : au-delà de 4 000 octets, le payload est présenté sous forme d'extrait accompagné de sa taille exacte et d'une empreinte SHA-256, plutôt que tronqué silencieusement.
- Fix — les échecs dans un lot
g2rd_batchne sont plus silencieux : un lot n'est désormais rapporté comme réussi que si toutes ses opérations le sont. L'ancienne règle — succès dès qu'une seule passait — faisait rapporter comme réussi un lot dont une opération avait été perdue, comme cette redirection jamais créée et découverte plusieurs heures plus tard. - Motif d'échec par opération : chaque opération porte son statut (
success,skipped,error), un message lisible et, le cas échéant, l'erreur SQL remontée par$wpdb->last_error. Le compte-rendu inclut un résumé du type « 6 opérations réussies, 2 en échec sur 8 ». - Préconditions vérifiées avant exécution : extension Redirection absente, FluentCart ou WooCommerce manquant, cible inexistante. Ces cas sont détectés en amont et signalés, au lieu d'échouer en silence une fois l'opération confirmée.
- Tests : 4 nouveaux, dont la reproduction exacte du scénario de production — un lot mixte où des opérations passent des articles en brouillon et où la dernière, sans paramètre
status, doit conserver le sien. Suite complète à 173 tests / 1 106 assertions.
- MCP — les opérations sur de gros contenus passent enfin : toute opération dont les arguments dépassaient ~49 Ko de JSON était refusée par un « Failed to enqueue operation », sans e-mail de confirmation. La colonne qui stocke les arguments chiffrés était en
TEXT(65 535 octets) alors qu'elle reçoit du base64, soit ~4/3 du JSON. Elle passe enLONGTEXTvia une migration idempotente, et un dépassement renvoie désormais une erreur qui nomme la taille reçue et la limite au lieu d'un « réessayez » trompeur sur un échec déterministe. Les échecs d'écriture remontent l'erreur MySQL réelle.
- MCP — contrôle complet des produits WooCommerce : cinq nouveaux outils,
g2rd_create-woo-product,g2rd_update-woo-product,g2rd_delete-woo-product(corbeille uniquement),g2rd_get-woo-productetg2rd_list-woo-products. Les outils existants sont inchangés. - Toute la fiche produit est pilotable : nom, slug, description longue et courte, statut, UGS, prix normal et promotionnel, gestion et quantité de stock, réappro, visibilité catalogue, produit virtuel ou téléchargeable, mise en avant, vente à l'unité, avis, TVA et classe de taxe, poids et dimensions, image principale, galerie, catégories, étiquettes, note d'achat et ordre d'affichage.
- Passage par les classes CRUD officielles (
WC_Product_Simple,WC_Product_Variable) et jamais par les métadonnées de publication : les hooks WooCommerce, les tables de recherche et les migrations futures restent valides. - ⚠ Les prix WooCommerce sont des montants décimaux, contrairement aux outils FluentCart qui attendent des centimes :
"200.00"vaut 200 €. Un agent qui reporterait l'habitude des centimes créerait un produit à 20 000 €. Trois garde-fous : le schéma l'indique explicitement, la validation refuse tout montant mal formé, et l'e-mail de confirmation affiche le prix en toutes lettres — un administrateur voyant « 20 000,00 € » pour un produit à 200 € refuse. - La virgule décimale française est acceptée (
"19,99"), puisqu'un agent reprend souvent le prix tel qu'affiché sur le site. - Refus explicites plutôt qu'échecs silencieux : un prix promotionnel supérieur ou égal au prix normal est rejeté — WooCommerce l'ignorerait et l'opération semblerait réussir sans effet ; un produit simple sans prix est rejeté car il ne pourrait pas être ajouté au panier ; chaque énumération invalide renvoie la liste des valeurs acceptées.
- Mise à jour partielle sûre : seuls les champs réellement fournis sont écrits, un champ omis n'est jamais réinitialisé.
- Écriture atomique : si l'enregistrement échoue en cours de route, le produit partiellement créé est retiré plutôt que de laisser une fiche invendable dans la boutique.
- Qualité : les capacités WooCommerce (
edit_products,delete_products…) sont déclarées dansphpcs.xml.distvia la propriété prévue par le sniff, ce qui préserve la détection des vraies fautes de frappe sur les capacités du cœur. Suite complète à 165 tests / 1 076 assertions.
- MCP — création de produits FluentCart exploitables : six nouveaux outils,
g2rd_create-product,g2rd_update-product,g2rd_delete-product(corbeille uniquement),g2rd_get-product,g2rd_list-productsetg2rd_list-post-types. La signature des outils existants est inchangée. - Le problème corrigé :
g2rd_create-postn'appelle quewp_insert_post(). Or FluentCart stocke le prix, le type de paiement et les variations dans ses propres tables (fct_product_details,fct_product_variations). Un produit créé ainsi apparaissait dans la liste des articles mais l'écran Pricing ne pouvait rien enregistrer et le produit n'était pas achetable.g2rd_create-productécrit désormais le post et les lignesfct_*, en passant exclusivement par les modèles officiels de FluentCart (FluentCart\App\Models\ProductDetail,ProductVariation) — aucun SQL brut, les hooks et migrations du plugin restent valides. - Écriture atomique : si une ligne
fct_*échoue, le post WordPress est supprimé. Plus de produit orphelin. - Prix en centimes entiers, contrat strict :
20000vaut 200,00 €. Une valeur décimale est refusée plutôt que tronquée —199.99converti en entier donnerait 199 centimes, soit 1,99 € au lieu de 199,99 €, sans la moindre erreur. - Abonnements : type de paiement, intervalle de facturation, nombre de périodes, jours d'essai, nombre de cycles ou renouvellement illimité, stock limité ou non, variation par défaut.
- Fix — validation du type de contenu à l'écriture :
wp_insert_post()ne vérifie pas qu'un type de contenu est enregistré ; il insérait donc un article orphelin, invisible de tous les écrans d'administration.g2rd_create-postvalide désormais avant d'écrire, et refuse explicitement les produits FluentCart en renvoyant vers l'outil dédié. - Fix — messages d'erreur exploitables :
g2rd_list-postsrépondait « Post type not accessible » pour un type inexistant, orientant vers un faux problème de permissions sans permettre de découvrir le bon identifiant. Il distingue maintenant les deux cas et liste les valeurs valides.g2rd_list-post-typesévite d'avoir à deviner. - E-mail de confirmation enrichi : il indique le produit et les tarifs qui seront enregistrés, et signale par avance une opération qui serait refusée. Approuver « créer un produit » sans en connaître le prix n'est pas une décision éclairée.
- Journalisation : chaque écriture produit est tracée dans l'audit log (utilisateur, opération, produit, tarifs, résultat).
- Tests : 18 nouveaux tests PHPUnit (contrat centimes, refus explicites, mapping des abonnements, libellés de prix, garde FluentCart absent, et les cas de mise à jour relevés en revue). Suite complète à 150 tests / 982 assertions.
- Fix — snippets de configuration MCP (onglet « MCP Tokens ») : la clé du serveur était codée en dur à
g2rddans les quatre snippets générés. Connecter un second site G2RD écrasait silencieusement la configuration du premier par copier-coller — les deux ne pouvaient pas coexister. La clé est désormais dérivée du domaine et du chemin du site :https://holtz-apiculture.fr/wp-json/donneg2rd-holtz-apiculture, et un sous-site de multisite en sous-répertoire obtient sa propre clé. Les deux snippets de repli, restes d'une version antérieure qui ne correspondaient plus aux formats générés, réutilisent maintenant les mêmes fonctions. Une note rappelle que le JSON est à fusionner dans l'objetmcpServersexistant, pas à coller à la place du fichier. - Fix — documentation du bridge stdio :
tools/g2rd-mcp-bridge.jsdocumentait l'endpoint/wp-json/g2rd/mcp/v1/au lieu de/wp-json/g2rd/v1/mcp, et un exemplecommand: "node"avec chemin absolu là où l'interface génèrecommand: "g2rd-mcp-bridge".
- Fix — bloc Compteur : les décimales ne sont plus arrondies : avec le réglage « Décimales » laissé à 0 (sa valeur par défaut), un compteur allant jusqu'à
5,5s'affichait6. Le nombre de décimales est désormais déduit des valeurs saisies lorsque le réglage explicite vaut 0 ; une valeur explicite supérieure à 0 continue de primer. Les champs « Nombre de départ » et « Nombre d'arrivée » acceptent enfin les décimales (step="any"), et l'aide du curseur précise que 0 signifie « automatique ». - Rétro-compatibilité : le HTML sauvegardé par le bloc est inchangé — aucune invalidation des compteurs existants, aucune migration nécessaire. Les compteurs portant sur des nombres entiers rendent exactement comme avant ; seuls ceux à valeur décimale, précisément ceux qui étaient affectés, changent d'affichage.
- MCP — réglages de plugins sous liste blanche : trois nouveaux outils permettent de piloter des réglages de plugins tiers depuis un client MCP, sans jamais autoriser d'écriture arbitraire.
g2rd/list-plugin-settings(introspection, ne renvoie aucune valeur),g2rd/get-plugin-setting(lecture) etg2rd/update-plugin-setting(écriture, soumise à la confirmation e-mail administrateur comme toute écriture MCP). Le moteurMcpPluginSettingsest générique : il ne connaît que ce que déclare sa constanteREGISTRY, et tout ce qui en est absent est refusé. - Périmètre initial : SEOPress PRO (activation du sitemap Google News, nom de publication, types de contenu inclus), Yoast SEO (sitemaps XML, séparateur de titres), WooCommerce (avis produits, codes promo, gestion des stocks). Toutes les clés d'options ont été relevées dans les sources des plugins, jamais devinées.
- Détection des paliers payants : un réglage peut déclarer un prérequis (
requires) évalué en plus de la présence du plugin. Les réglages Google News vivent dans l'option PRO de SEOPress, or le plugin gratuit définit lui aussiSEOPRESS_VERSION— sans ce garde-fou, l'écriture aurait réussi en base pendant que SEOPress ignorait la valeur. L'introspection expose le résultat via un drapeauavailable. - Écriture chirurgicale : les options stockées en tableau sérialisé sont lues, modifiées sur la seule sous-clé ciblée, puis réécrites — les réglages voisins sont préservés. La sanitisation est déclarée par réglage et non déduite, les plugins ne s'accordant pas sur le stockage des booléens (
'1'/absence, booléen PHP,'yes'/'no'). - Sécurité :
manage_optionsexigé, scopeeditorrequis à l'écriture, refus de toute entrée évoquant un secret (mot de passe, clé d'API, token, sel, licence), valeur précédente conservée pour rollback, et journalisation complète dans l'audit log. - Effets de bord : purge du cache après écriture, et
flush_rewrite_rules()pour les réglages de sitemap — sans quoi/news.xmlrenvoie un 404 malgré son activation. - Tests : 15 tests PHPUnit couvrant le cas nominal, la préservation des clés sœurs, les refus hors liste blanche, l'absence de capacité et le non-contournement de la confirmation.
- Sécurité — 12 alertes Dependabot corrigées, retour à 0 : mise à jour de 11 paquets de la chaîne de build (
svgo,immutable,brace-expansion,linkify-it,postcss,fast-uri,js-yaml,shell-quote,webpack-dev-server,nanoid,body-parser). Tous en scopedevelopment: le thème n'ayant aucune dépendance npm en runtime (dependencies: {}), aucun de ces paquets n'est livré sur les sites. Correctifs appliqués dans les ranges semver existants —@wordpress/scriptsreste en 33.0.0, aucune rétrogradation de la chaîne de build. - Style — nouveau screenshot du thème.
- Chore — map d'autoload Composer régénérée : ajout de
G2RD\GlobeEffectetG2RD\ThemeDownload, déjà présentes dans le dépôt mais absentes de la map.
- Style — section « Le profil » (pages membre) : le rendu PHP de la section injectée après le contenu (Expérience, Soft skills, Méthodologie, Objectif, Stack technique) est réaligné sur le design des pages membre. Bande pleine largeur crème, pill « Le profil » identique à la pill de page (lime pleine + puce ●), titre centré à soulignement lime, cartes
is-style-cardavec libellé en label majuscule et valeur enprimary(contraste 17:1 au lieu dumuted4.56:1). Cohérence visuelle totale avec le reste de la page.
- Fix — champs membre (Qui sommes-nous) enfin affichés : la section « Le profil » (Expérience, Soft skills, Méthodologie, Objectif, Stack technique) ne s'affichait pas sur les pages membre. Cause : en FSE, le template n'est pas rendu dans une boucle
the_post(), donc le gardein_the_loop()du filtrethe_contentrenvoyait toujoursfalse. Corrigé : garde basé surget_queried_object_id()(fiable pour un singular) + drapeau anti-double-rendu. Rendu 100 % PHP, indépendant du template → ne peut plus être perdu lors d'un ré-enregistrement dans l'éditeur de site. - Nettoyage : suppression du code mort devenu inutile (5 shortcodes membre
[experience_dev]/[soft_skills]/… + la source de block bindingg2rd/member-meta) — 0 référence, remplacés par le renduthe_content. Les shortcodes et le binding portfolio sont conservés (toujours utilisés). - Fix : référence morte
var(--wp--preset--color--border)→var(--wp--custom--color--border)dans le rendu de la section membre (suite au déplacement deborderen 1.26.2).
- Fix — collision
.has-border-color: le slugborderde la palette générait automatiquement l'utilitaire WordPress.has-border-color { color: … !important }, qui écrasait la couleur du texte de tout bloc doté d'une couleur de bordure nommée (sur toutes les variations de style, dont Bela Vista).borderest déplacé de la palette verssettings.custom.color(socle, hérité par toutes les variations) → WordPress ne génère plus l'utilitaire fautif. Les 20 références migrées devar(--wp--preset--color--border)versvar(--wp--custom--color--border)(même valeur#e2e8f0) : les bordures des cartes (is-style-card, etc.) restent identiques. - Note :
surfacereste en palette (aucune collision). Aucun changement visuel des bordures, uniquement suppression de l'écrasement parasite de couleur de texte.
- Fix — champs membre (Qui sommes-nous) : la section « Le profil » (Expérience, Soft skills, Méthodologie, Objectif, Stack technique) est désormais rendue en PHP (filtre
the_content) après le contenu sur les pages membre — approche robuste indépendante du markup du template, qui survit aux ré-enregistrements dans l'éditeur de site (l'ancienne section en block bindings était perdue à chaque sauvegarde). Couleurs 100 % tokens → suit le style actif. - Bloc CTA Band : couleurs par défaut migrées vers les tokens du thème (
primary/white/secondary) avec déprécation — les blocs existants restent valides puis migrent en douceur à la ré-édition. - Nettoyage : retrait de ~130 lignes de code mort dans
class-block-styles.php(chargement de styles jamais exécuté + cache inerte).
- Accessibilité des blocs (RGAA/WCAG) : autoplay des carrousels/sliders pausable au clavier (WCAG 2.2.2) + module
Swiper.A11y(aria-roledescription, live region) ; respect deprefers-reduced-motionsur carrousel, slider, countdown, effect-kits et particules (animations neutralisées, éléments toujours visibles). - Couleurs 100 % tokens dans les templates : conversion de toutes les couleurs codées en dur (ancienne palette navy/tan) vers
var(--wp--preset--color--…)dans l'ensemble des templates — le rendu suit désormais la variation de style active. Contrasteaccentaligné AA (#e11d48). - Import header/footer fiabilisé : nouveau filtre
FseSync::normalize_template_part_theme()qui neutralise l'attributthemedescore/template-partau rendu → plus d'erreur « template part supprimé ou non disponible », même après une re-sauvegarde dans l'éditeur de site (fichier et BDD). - Design-system : tokens
border/surface, gradientsecondaryet alias structurels ajoutés aux variationsg2rd-style,apiculteuretbela-vista(cartes, boutonsoutline/actionet sections sombres corrects sur chaque style). - Page d'options (BO) : accessibilité corrigée (labels sur tous les interrupteurs et champs,
<h1>, état React au lieu de lecture DOM), polices Inter self-hostées (fin de l'@importGoogle Fonts — perf + RGPD), suppression de code mort (SaveBar.js). - i18n : correction du textdomain
wrb→g2rdsur 19 blocs (365 chaînes) — libellés d'éditeur enfin traduisibles. - Performance : exclusions LiteSpeed pour
gsap-animation.jsetcarousel-frontend.js(données localisées non réordonnées). - Correctifs : template
single(groupe non fermé), header/footer (is-style-primaryinexistant → attributs FSE réels),single-prestations(attributtheme), style de bouton « Alternatif » (contraste blanc→navy sur lime),template-vtc(cléstyledupliquée), attributsalt/ariamanquants (sidebar, share-buttons, geo-faq).
- Nettoyage de
style.css: retrait de ~284 lignes de CSS legacy mort — TranslatePress (.trp-*), cookies SeoPress (.seopress-*), template produit FluentCart (.g2rd-product-*, orphelin : plus aucun template ne l'émet),.resize-img,.ti-widget. Fichier allégé de 666 → 397 lignes..img-h-100conservée (utilisée par les patternsgrid-portfolioetpost-grid). Aucun impact visuel : uniquement du code mort — vérifié par diff règle-à-règle, aucune règle partagée modifiée, les variations de style (bela-vista, apiculteur…) sont strictement inchangées. Première étape de l'isolation « chacun son style » : le CSS spécifique à chaque projet migrera ensuite vers sa variationstyles/*.json. - Champs membre FSE (Qui sommes-nous) : nouvelle source de block binding
g2rd/member-meta— les champs Expérience, Soft skills, Méthodologie et Objectif s'affichent désormais via des paragraphes natifs liés (valeur réelle visible dans l'éditeur de site et en front, principe FSE). Section « Le profil » restaurée et harmonisée danssingle-qui-sommes-nous.html(pill lime en aplat, cartesis-style-card) — ces champs avaient disparu du template lors de la refonte 1.8.0. Icônes affichées en rangée via le shortcode[icones_images]amélioré. - Template produit FluentCart : nouveau modèle
single-fluent-products.html(fil d'Ariane, galerie, prix, ajout au panier, description) pour la fiche produit FluentCart.
- Uniformisation de l'interface des blocs : les 20 blocs G2RD partagent désormais la même organisation de l'inspecteur — onglets natifs de WordPress (Réglages / Styles / Avancé), vocabulaire de panneaux commun (
Dimensions,Arrière-plan,Couleur,Bordure,Animation…) et contrôles natifs (ToggleGroupControlà la place des boutons maison). Chaque réglage se retrouve au même endroit d'un bloc à l'autre. LeTabPanelmaison du Conteneur est remplacé par les onglets natifs. Rendu front strictement identique : seul l'inspecteur change,save.js/render.php/block.jsonrestent inchangés. - Sécurité (Conteneur G2RD) : blocage d'une injection CSS possible via les attributs du bloc.
sanitize_text_field()laissait passer{ } ; @, permettant à un contributeur de fermer la déclaration et d'injecter des règles CSS arbitraires dans le<style>du bloc. Les valeurs de style sont désormais filtrées (g2rd_css_value()), les énumérations validées par liste blanche. - Outillage / CI :
@wordpress/scriptsmonté en33.0.0(overridewebpack ^5.108.1pour éviter la duplication d'instance) ; protection de la branchemainexigeant les status checks avant fusion ; Dependabot bridé sur les montées majeures de la chaîne de build.
- Agent Discovery —
/auth.md: le thème sert désormais/auth.mdà la racine (spec auth.md), décrivant aux agents IA comment s'authentifier. Document self-contained et honnête : endpoints publics sans authentification, et — sienable_aiest actif — API MCP surPOST /wp-json/g2rd/v1/mcppar jeton Bearer délivré manuellement par l'admin (scopesread_only/editor, écritures en file d'approbation). Aucun blocagent_auth/register_urin'est publié : le site n'opère pas de serveur d'autorisation OAuth 2.0/OIDC et la spec ne l'impose que dans ce cas. Filtreg2rd_auth_mdpour personnalisation. - Correction de documentation :
CLAUDE.mdindiquait l'endpoint MCP/wp-json/g2rd/mcp/v1alors que la route réelle est/wp-json/g2rd/v1/mcp.
- Accessibilité — deux options indépendantes : le bouton « retour en haut » est désormais une fonctionnalité distincte du panneau d'accessibilité (nouvelle feature
back_to_top, activée par défaut). On peut activer l'un sans l'autre depuis l'onglet Éditeur. - Couleur des boutons flottants : nouveau réglage pour choisir la couleur des boutons « accessibilité » et « retour en haut » dans la palette du thème (stockée en slug →
var(--wp--preset--color--slug), suit la variation de style active). Section « Couleur des boutons flottants » dans l'onglet Éditeur. - Fix panneau d'accessibilité : le panneau apparaissait en bas du document (au lieu d'être collé au bouton) lorsqu'un ancêtre était transformé (
transform/filter/will-change). Bouton et panneau sont désormais solidaires dans un conteneur fixe.a11y-widget, le panneau étant ancré au-dessus du bouton. Ajout de fallbacks--primary/--whitepour les variations sans ces slugs.
- Variation Bela Vista : header responsive — items de navigation et
.bv-tel(téléphone) enwhite-space:nowrap, et media querymax-width:1180pxréduisantfont-size/gapde la navigation. Garde le header enrichi (logo + menu + téléphone + bouton) sur une seule ligne, puis le réduit proprement avant le passage en menu mobile. Barre d'annonce et rangée de navigation (.bv-promo.alignwide/ nouvelle classe.bv-nav-row.alignwide) élargies àmax-width:1560px.
- Variation Bela Vista : ajout du token de couleur
green-soft(#EAF3EE) à la palette et de nouveaux helpers CSS —.bv-anchors(ancres pilule scrollables),.bv-toc(sommaire collant),.bv-doc(mise en forme document légal : titres, listes, liens),.bv-step/.bv-num,.bv-idcard,.bv-resbaret.g2rd-breadcrumb. JSON validé, toutes les référencesvar(--wp--preset--…)résolvent.
- Conteneur G2RD — Position collante (sticky) : nouveau panneau « Position collante » (onglet Mise en page, sous Dimensions) permettant de rendre le bloc collant au défilement — il suit le contenu et reste visible dans sa colonne (ex. sommaire latéral), puis s'arrête à la fin de la colonne. Toggle d'activation + décalage haut réglable (px/rem/em). Appliqué en aperçu éditeur et en CSS front (
position:sticky,align-self:flex-start), prioritaire sur leposition:relativede l'overlay.
- Variation Bela Vista : mise en charte du formulaire FluentForm (
.bv-form .fluentform— labels, champs, focus, checkbox, bouton d'envoi pétrole en pilule, messages succès / erreur) et du bloc carte (.bv-acc .g2rd-map, coins arrondis). Couleurs 100 % issues de la palette de la variation.
- Fix Conteneur G2RD (animations) : les conteneurs avec une animation d'entrée (
fadeInUp…) restaient invisibles sur le front — le CSS les masque (opacity:0) en attendant la classe.g2rd-animated, mais le script chargé de la poser était absent (aucunviewScript). Ajout deview.js(IntersectionObserver: révèle à l'entrée dans le viewport, applique durée/délai/easing ; repli immédiat enprefers-reduced-motion) et déclaration duviewScriptdansblock.json.
- Variation Bela Vista : finalisation du style bouton — plus d'ombre au repos, ombre
belauniquement au survol (bouton plein et variation « outline ») ; variation outline complète (fond transparent, bordure pétrole pilule, padding / typo alignés). Nouveaux helpersstyles.css: formulaire (.bv-form,.bv-field,.bv-consent, bouton pleine largeur), légendes (.bv-legend), plan (.bv-plan), grille 2 colonnes responsive (.bv-grid2), titre à mot manuscrit (.bv-title-script).
- Fix Conteneur G2RD : correction des layouts Grille et Flex dont les blocs enfants s'empilaient au lieu de se répartir en colonnes / en ligne. Cause : un double conteneur (wrapper de
save()+ wrapper derender.php) et l'imbrication desInnerBlocksdans l'éditeur. Le layout s'applique désormais directement aux enfants (useInnerBlocksProps+save()nu), avec déprécation et déballage compat pour le contenu déjà enregistré. - Variation Bela Vista : enrichie — polices
@font-face(Poppins, Dancing Script), presets d'ombres, variation de bouton « outline », spacings alignés sur le thème et feuillestyles.cssd'helpers de mise en page.
- Variation de style « Bela Vista » : nouvelle variation FSE (
styles/bela-vista.json) — charte pétrole & ciel, typographies Poppins + Dancing Script, boutons pilule. Sélectionnable dans l'éditeur de site.
- Template prestations : refonte « content-first » de
single-prestations.html— suppression du hero sombre en haut (le contenu démarre directement sous le header, plus d'espace blanc), ajout d'une navigation article précédent/suivant, conservation des sections « D'autres services » et CTA « Prêts à travailler ensemble ». - Fix articles cliquables : la détection du lien dans une carte cliquable prend désormais en compte un lien qui est un enfant direct du groupe (bloc
read-more), et plus seulement un lien imbriqué dans un enfant. Rétablit le clic sur les cartes (prestations, portfolio, articles…) dont le lien provient du bloc « Lire la suite ».
- Fix portfolio : le bouton « Visiter le site » de
single-portfolio.htmlpointe enfin vers l'URL du projet. Enregistrement de la source de block bindingg2rd/portfolio-link(lit le champ_portfolio_linkdu CPT portfolio) et câblage du bouton du template sur ce binding — un champ meta protégé ne peut être lu ni par un shortcode ni parcore/post-meta, d'où la source custom.
- Fix activation du globe : l'animation globe est désormais pilotée par la classe
g2rd-globe-bg(source unique de vérité). Décocher le toggle de la sidebar retire réellement le globe — y compris sur les sections dont la classe provient d'un pattern/template (l'ancien attribut ne supprimait pas la classe manuelle). - Globe — UX : le panneau « Animation globe » n'apparaît que sur les sections sombres (
is-style-section-dark) ; la position devient une classeis-globe-{position}; le réglage fin (décalage/taille) est conservé avec aperçu temps réel. - Globe — simplification : suppression de l'interrupteur global dans la page d'options (activation par section uniquement) et nettoyage de l'ancien attribut
globeEffect.
- Globe — positionnement précis : les positions droite / gauche / haut / bas sont recentrées (le globe reste entièrement visible, plus de découpe), et un réglage fin est ajouté dans la sidebar — décalage horizontal / vertical (px) et taille — avec aperçu en direct dans le BO et sur le front.
- Grille filtrable — CTA façon natif WordPress : les réglages du bouton (couleurs, padding, rayon, bordure, alignements titre / extrait / bouton) passent dans l'onglet Styles avec des composants natifs (
UnitControl,ToggleGroupControl). Nouvelle bordure activable (largeur + couleur + style,BorderControl). Aperçu temps réel dans l'éditeur (rendu inline).
- Animation globe : le globe filaire devient une fonctionnalité activable / désactivable depuis la page d'options (activée par défaut), avec choix de la position (centre / droite / gauche / haut / bas) par section depuis la sidebar de l'éditeur, et aperçu en direct dans l'éditeur WordPress (CSS chargé aussi dans le canvas). CSS extrait de
style.cssversassets/css/globe.css. - Grille filtrable : nouveaux réglages du bouton CTA (couleur fond / texte + survol, padding, rayon, alignement) et alignement des textes (titre, description) depuis l'inspecteur — les overrides ne s'activent que s'ils sont réglés (style de bouton natif préservé par défaut).
- Fix Magic Page (front) :
magic-page.cssest désormais chargé sur le front pour les sectionsis-style-magic-dark/is-style-magic-light(et les boutonsneomorphic/soft-pressed), y compris quand elles vivent dans un template FSE. La détection couvre tous les marqueurs du design system (plus seulement la chaîneg2rd-magic-page) et résout le template de bloc courant — corrige le fond blanc des sections Magic sur le front (le chargement viastyle_handleau rendu n'était pas imprimé dans le<head>).
- WP Manager — généralisation : les 19 templates FSE (archives, singles,
page-*,home,search,taxonomy) alignés sur la charte — coversbleubeige→ sections sombresis-style-section-dark+ globe, pill eyebrows lime, cartesis-style-card, boutonsis-style-action/is-style-outline, liensaccenthover(AA). - Section wp-manager : nouveau pattern réutilisable
section-wp-manager.php(mock dashboard 100 % natif + CTA verswp-manager.g2rd.fr), inséré avant la FAQ de l'accueil. - Globe géodésique filaire : SVG icosphère
assets/img/wire-globe.svgen fond des sections.is-style-section-dark.g2rd-globe-bg(couleur pilotée par le token lime, rotation lente,prefers-reduced-motion). - Patterns : sections (services, cta, témoignages, faq…) et cartes (box, info-box, contact, details, présentation…) modernisées ; slugs périmés purgés (
tertiary,main,base,main-accent,border-dark,spacing|large/medium/small). - Contenus Gutenberg : dossier
Gutenberg/(15 pages + template single, prêts à coller) — exclu du ZIP de production. - Fix : FAQ + JSON-LD
FAQPagedupliqués retirés (le blocg2rd/faqgénère déjà son schéma), zéro CSS personnalisé dans les pages, zéro couleur en dur.
- Refonte design — alignement wp-manager : palette recalée sur le SaaS
wp-manager.g2rd.fr(navy#0f172a, lime#a3e635, dégradé magenta-violet) + slugs sémantiquesborder/surface/success/warning/danger. - Variations de styles (FSE, tokens uniquement, zéro CSS) :
core/group→ Section sombre, Carte, Carte sombre, Carte action (dégradé) ;core/button→ Action (dégradé), Ghost, Outline. - Composants modernisés : hero (pill, titre avec mot-clé surligné lime, double CTA, stats, halo radial), headers (×2) et footer avec boutons « Se connecter » (→
g2rd.fr/account/) et « Contact » (→g2rd.fr/contact/), nouveaux patterns « bandeau de chiffres » et « cartes statistiques ». - Animations : hover lift sur cartes/boutons, halo radial des sections sombres (
color-mixsur tokens), respect deprefers-reduced-motion. - RGAA : lime en aplat uniquement, dégradé d'action assombri pour contraste AA du texte blanc, liens en pink-600 (AA), tout en
var(--wp--…)/color-mix. - Docs :
DESIGN_AUDIT.md(extraction + mapping FSE) etCHANGELOG_DESIGN.md.
- Charte graphique : nouvelle palette navy/lime/rose en remplacement de bleu/beige.
- Couleurs dynamiques : tout le markup (patterns, parts, templates) et le CSS référencent les variables de la palette (
var(--wp--preset--color--*)+color-mix()pour les translucides) — un changement de charte ou de variation de style se propage automatiquement à tous les blocs, sans repasser sur chacun. - Fix template parts : résolution robuste du header/footer (retrait de l'attribut
themecodé en dur dans leswp:template-part) — corrige l'erreur « élément de modèle supprimé ou non disponible » sur une install neuve ; suppression du template part fantômenewsletter. - Maintenance : mises à jour de dépendances Dependabot (
@wordpress/scripts32.5.0,@playwright/test1.61.1).
- Accessibilité (RGAA) : compteurs affichant leur valeur réelle sans JS, liens de navigation
href="#"redirigés vers une vraie destination, emojis décoratifs masqués aux lecteurs d'écran (aria-hidden),alt=""de secours sur les images de galerie,autocomplete+ association label/champ sur les formulaires. - Accessibilité (structure) : repère
<main>ajouté à 15 templates — lien d'évitement fonctionnel sur toutes les pages. - Fix : réparation de
archive-prestations.html(tronqué depuis la 1.8.0 — pied de page et structure restaurés). - Grille filtrable : CTA transformé en bouton WordPress natif avec choix du style natif (cohérence graphique) ; tailles de titre et d'extrait désormais appliquées côté front.
- Style : refonte et réorganisation de
style.cssen sections structurées (variables:root, reset FSE, animations, images, articles cliquables, effet glass, particules, template produit FluentCart, responsive). - Fix : montée de version pour forcer le rafraîchissement du cache navigateur — les modifications CSS de
style.cssn'étaient pas prises en compte tant que la version (cache-buster?ver=) restait identique.
- Fix mises à jour du thème : la dernière release GitHub est désormais mise en cache (6 h, transient partagé par la vérification de MAJ et la fiche thème). Fini l'épuisement du quota API GitHub lors des snapshots REST du connector, qui faisait disparaître la mise à jour du thème custom dans le manager.
- Robustesse : un
403 rate limit(qui n'est pas une erreur WP) est désormais détecté via le code HTTP, avec backoff de 15 min ; une mise à jour déjà connue n'est plus jamais effacée par un appel raté.
- MCP —
g2rd_create-full-post: crée un article complet (contenu, image à la une importée depuis une URL, catégories, tags, métas SEO) en un seul appel et une seule confirmation e-mail, là où il fallait 4 actions auparavant. - MCP —
g2rd_batch: regroupe jusqu'à 20 actions d'écriture en une seule confirmation (exécution séquentielle, statut par opération). - Sécurité : vérification du type MIME réel des médias importés (sideload), bénéficiant aussi à
g2rd_upload-media; rollback automatique du média si la création de l'article échoue. - Style : clarification du libellé de licence dans l'onglet Licence (FluentCart).
- Fix IA : fiabilisation de la persistance du « Profil du site » (sauvegarde indépendante de la méthode HTTP, en-tête anti-cache, et garde-fou de diagnostic si une écriture d'option est bloquée).
- Profil du site IA : le contexte (activité, ville, cible, ton) se saisit une seule fois dans Options G2RD → IA, puis est réinjecté automatiquement dans toutes les générations — fini la re-saisie dans chaque bloc.
- Connecteur WordPress AI : l'inférence passe par le WordPress AI Client (providers Anthropic/OpenAI) avec repli automatique sur l'appel direct Anthropic.
- Panneau IA simplifié dans les blocs (Hero, FAQ, CTA, Tarifs, Témoignage, Card) : plus de champs de contexte répétés.
- Fix FluentCart : reconnaissance du post type produit
fluent-products(mise à jour de la version produit à chaque release). - Grille filtrable : nouveaux contrôles du CTA (padding, bordure complète, rayon) — valeurs CSS libres (dont
clamp()pour un rendu fluide), visibles dans l'éditeur et sur le front.
- Téléchargement FluentCart (g2rd.fr) : nouvel endpoint sécurisé
/download/g2rd-theme.zip?license=…qui valide la licence et streame le ZIP depuis un cache local hors webroot, mis à jour automatiquement à chaque release. - Livraison automatisée : lien de téléchargement de la dernière version ajouté dans l'email d'achat et dans l'espace client (onglet Licences).
- Admin licences : alignement de l'onglet de gestion des licences (TabLicenceAdmin).
- theme.json enfant prioritaire : le
theme.jsond'un thème enfant pilote désormais entièrement les réglages qu'il définit — palette, polices, espacements remplacent ceux du parent (deep-merge « enfant prioritaire ») ; les réglages absents héritent du parent. - Point d'extension
externalTabs: onglet externalisable sur la page d'options (filtre PHP + hook JS) pour brancher des modules tiers. - Bridge MCP — debug optionnel : les traces du bridge stdio sont conditionnées à la variable
G2RD_MCP_DEBUG(silencieuses par défaut). - Maintenance : montée de
@wordpress/scripts(Dependabot).
- Fix : support thème enfant dans
composeThemeJson()— les couleurs définies dans letheme.jsondu thème enfant sont désormais fusionnées avec celles du parent (ajout + surcharge par slug). La clé de cache intègre lemtimedutheme.jsonenfant pour une invalidation automatique à chaque modification.
- Fix : renommage des 37 outils MCP de
g2rd/xxxversg2rd_xxxpour respecter le pattern imposé par l'API Anthropic (^[a-zA-Z0-9_-]{1,64}$) — corrige le rejet detools/listpar Claude Desktop.
- Feature : Nouvel outil MCP
upload-media— télécharge une image depuis une URL et l'importe dans la médiathèque WordPress (types autorisés : jpg, png, gif, webp, svg, pdf ; limite 10 Mo). - Feature : Nouvel outil MCP
upload-media-base64— importe un fichier encodé en base64 dans la médiathèque (utile pour les images générées par Claude). - Feature : Nouvel outil MCP
delete-media— déplace un attachment en corbeille (suppression permanente impossible). - Refactor : MCP passe de 34 à 37 outils.
- Feature : MCP WordPress étendu à 34 outils —
get-postavec HTML, taxonomies, SEO et image mise en avant ;list-postsavec filtres statut/recherche/catégorie/tag ; nouveaux outils lecture (get-post-meta, list-categories, list-tags, list-media, get-seo-data, get-seo-overview, get-redirections, list-plugins, get-theme-info, list-themes, get-options, get-users, get-site-health, get-cron-jobs, list-menus). - Feature : 15 outils d'écriture MCP avec confirmation admin (delete-post, update-post étendu, update-post-meta, update-seo-data, create-redirection, create-category, create-tag, update-media, activate/deactivate/update-plugin, update-option whitelist, flush-cache, update-menu-item).
- Refactor : déplacement
export-theme.ps1danstools/.
- Fix : bridge MCP — ne répond plus aux notifications MCP (corrige l'erreur de validation
invalid_uniondans Claude Desktop).
- Fix : endpoint MCP déplacé de
g2rd/mcp/v1/versg2rd/v1/mcp— corrige la 404 sur Hostinger (conflit avec le plugin AI Assistant natif).
- Fix : double préfixe URL dans
apiFetch—restUrl(URL absolue) remplacé parrestPath(chemin relatif/g2rd/v1/ai/), corrige le 404 sur la génération IA en production.
- Fix : Message "Connecteur IA non configuré" remplacé par un lien cliquable vers Apparence › Options G2RD › IA.
- Fix : Thème sombre (dark chrome) retiré de la modal et du launcher IA — rendu neutre WordPress.
- Feature : Module IA G2RD — appel direct Anthropic (claude-sonnet-4-6), sans dépendance à
wp_ai_client()ni plugin tiers. Clé API saisie dans les réglages, masquée en base. - Feature : Refonte UI assistant IA — sidebar remplacée par une modal plein-écran (contexte, onglets, résultat inline avec Insérer / Copier / Régénérer).
- Fix : Validation IP stricte (
filter_var FILTER_VALIDATE_IP) aux points d'entrée MCP et REST IA. - Fix : Suppression optimiste des tokens MCP + config Claude Desktop via commande
g2rd-mcp-bridgenpm-link. - Fix : Suppression ignore PHPStan
wp_ai_clientdevenu obsolète.
- Fix : révocation d'un token MCP supprime immédiatement l'enregistrement en base de données.
- Feat : tokens MCP inactifs (révoqués/expirés) visibles avec badge statut + bouton « Supprimer » (purge BD).
- Fix : bridge MCP enveloppe les erreurs WordPress en JSON-RPC valide — élimine l'erreur de validation Zod côté Claude.
- Feat : g2rd-mcp-bridge déclaré comme binaire npm global (
npm link) — configuration Claude.ai MCP sans chemin absolu.
- Feat : champ « Consignes personnalisées » dans les réglages Module IA (contexte site injecté dans le prompt).
- Feat : G2RDAiInspectorPanel intégré dans les blocs Pricing Table et Testimonial.
- Feat : compilation fr_FR.mo automatisée en CI lors des releases.
- Fix : source maps désactivées en production + .map existants supprimés du dépôt.
- Fix : wp_kses_post appliqué sur echo $markdown dans AgentDiscovery (PHPCS).
- Fix : webpack-dev-server mis à jour vers ^5.2.4 (vulnérabilité Dependabot #59).
- Test : couverture PHPUnit LicenseManager + GithubUpdater (29 tests).
- Docs : stratégie vendor/ documentée dans docs/internal/vendor-strategy.md.
- Module IA G2RD : nouveau module complet (AiModule, AiClient, AiRest, AiPrompts) — génération de contenu via WordPress AI Connectors, désactivable depuis la page d'options.
- Panneau IA dans les blocs : G2RDAiInspectorPanel intégré dans Hero, FAQ, CTA Band, Pricing Table, Testimonial et Card.
- Tab "Module IA" : nouvelle section dans la page d'options pour configurer les paramètres IA (activation, quotas, ton/longueur par défaut).
- Bridge MCP stdio :
tools/g2rd-mcp-bridge.js— connecteur Claude Desktop via stdio pour le serveur MCP WordPress. - Fix : endpoint MCP corrigé dans TabMcpTokens (
g2rd/v1→g2rd/mcp/v1/), config Claude Desktop générée au bon format stdio. - Fix : exclusion CSS LiteSpeed pour
accessibility.css— le panneau d'accessibilité s'ouvre correctement après optimisation LiteSpeed.
- Feat (filterable-grid) : couleurs CTA personnalisables — fond, texte, survol fond, survol texte — via PanelColorSettings dans l'inspecteur Gutenberg.
- Fix (filterable-grid) : caractères spéciaux (apostrophes typographiques
’, entités HTML nommées) s'affichaient littéralement dans les titres, extraits et noms de termes.
- Fix : page d'options admin inaccessible via
admin.php?page=g2rd-options— le slug enregistré étaitg2rd-theme-settings(incohérence avec tous les liens du thème). - Fix : navigation par hash dans la page d'options —
#mcp-queue(et tout onglet) dans l'URL ouvre directement le bon onglet. - MCP : code d'intégration complet (config Claude Desktop + Claude Code) affiché à la création d'un token API, et bouton "Voir config" sur chaque token existant.
- Fix critique : CSS des blocs
g2rd-card,g2rd-carousel,g2rd-countdown,g2rd-dynamic-content,g2rd-geo-faq,g2rd-geo-summary,g2rd-info,g2rd-typedjamais livré en production —block.jsonpointait verssrc/*.cssexclu du ZIP de production. Migré versbuild/*.cssgénéré par webpack.
- Fix (éditeur) : supprime les warnings de dépréciation
SelectControletRangeControlWP 6.8+ —__next40pxDefaultSizeet__nextHasNoMarginBottomajoutés sur 65+74 occurrences dans 24 fichiers, compatibilité assurée jusqu'à WP 7.1. - Feat (blocs) : dépréciations automatiques
g2rd-card(4 versions),g2rd-advanced-heading(fontSizeValue→fontSize) etg2rd-countdown(valueSize/labelSize→valueFontSize/labelFontSize) — migration silencieuse des blocs existants lors d'une mise à jour thème sur un site client. - Chore : bump
@playwright/test1.59.1 → 1.60.0.
- Fix (Card) : contrôle "Alignement des éléments" fonctionnel — passage à la CSS custom property
--g2rd-card-alignpour éliminer tout conflit de cascade entre inline style et sélecteurs CSS. - Fix (Card) : overlay lien carte entière — ajout
cursor:pointer, effet hover (fond semi-transparent) etfocus-visibleoutline pour l'accessibilité clavier.
- Fix (Card) :
align-items: centersur les positions gauche/droite — icône et contenu correctement alignés sur la même ligne. - Fix (Card) :
display: blocksur l'overlay link (correction rendu lien carte entière). - Fix (MCP) : migrations tables déclenchées sur
after_setup_theme— tables créées lors des mises à jour GitHub (plus seulement à l'activation). - Fix (MCP) : affichage du nom du token dans le tableau de la page d'options.
- Fix (Filterable Grid) : titres et extraits avec apostrophes ou accents affichés correctement —
wptexturize()convertissait les apostrophes en entités HTML (’) double-échappées par le JS. - Feat (Card) : nouveaux contrôles dans l'onglet Styles — alignement global des éléments (
align-items), écart média/contenu, écart entre éléments du contenu.
- Fix : Migrations MCP déclenchées sur
after_setup_theme— tableswp_g2rd_mcp_tokensetwp_g2rd_mcp_audit_logcréées lors des mises à jour GitHub (plus seulement à l'activation initiale). - Fix : Page d'options — onglet Tokens MCP affiche correctement le nom du token (
token_name).
- Fix : Bloc Card —
URLInputimporté depuis@wordpress/block-editor(était@wordpress/components→ erreur à l'ouverture du panneau CTA). - Feature : Bloc Card — position icône/image en haut alignée sur l'alignement du texte (gauche/centre/droite).
- Feature : Bloc Card — toggles pour masquer/afficher le sous-titre et la description (éditeur + front).
- Feature : Bloc Card — mode de lien exclusif : Désactivé / Bouton CTA / Carte entière cliquable (overlay
<a>absolu).
- Feature : Contrôle de taille typographique par élément sur 14 blocs — panneau "Typographie" dans l'onglet Styles (presets S/M/L/XL/XXL du thème).
- Feature : Composant partagé
TypographySizePanel— architecture unifiée,FontSizePickerpresets, aucune duplication entre blocs. - Feature : Page d'options admin — refonte visuelle complète (sidebar nav groupée par section, thème clair, polices Outfit + JetBrains Mono).
- Feature : SBOM CycloneDX JSON — inventaire automatique des dépendances PHP + npm sur chaque release GitHub.
- Fix : Audit MCP — câblage
X-G2RD-Screen,User-Agentetexecution_msdans l'audit log (SP-1). - Fix :
McpTokenManager— passage du paramètre$auditmanquant, correctif PHPStan.
- Fix MCP audit : câblage de
X-G2RD-Screen,User-Agentetexecution_msdans chaque entrée d'audit (allowed et denied) — complète l'intent du JS bridge (SP-5). - CI SBOM : nouveau workflow
sbom.yml— génère un inventaire des dépendances CycloneDX JSON (Composer PHP + npm) signé via attestation sigstore et attaché à chaque GitHub Release. - Thème enfant : dossier
g2rd-child/ajouté localement (non versionné) avecstyle.css,functions.php,theme.jsonet palette de design prête à l'emploi. - Chore : autoload Composer mis à jour pour
McpAbilities,McpConfirmationQueueetMcpServer.
- Option BO : bouton pause désactivé nativement sur tous les blocs animés (g2rd-carousel, g2rd-typed, g2rd-marquee, g2rd-testimonial) — activable via un toggle dans le panneau d'inspection Gutenberg.
- Accessibilité RGAA 10.1 :
:focus-visiblesur boutons carousel, counter, login, options-page, code éditeur. - Accessibilité RGAA 13.1 :
prefers-reduced-motionsur carousel, marquee, testimonial, typed. - Accessibilité RGAA 13.2 : bouton pause ⏸ sur marquee (g2rd-marquee + g2rd-testimonial), carousel autoplay, typed animation en boucle.
- Accessibilité RGAA 2.4 :
aria-label="En-tête coloré"sur header-color.html. - Accessibilité RGAA 9.1 :
<blockquote>/<cite>sémantique sur le bloc testimonial (mode manuel + Google Reviews). - Accessibilité RGAA 12.8 :
aria-current="page"dynamique sur les liens de navigation actifs. - Accessibilité RGAA 4.1/12.8 : focus trap + retour de focus sur g2rd-modal et g2rd-sliding-panel.
- Accessibilité RGAA 10.2 :
aria-hiddendynamique sur le contenu masqué de g2rd-toggle-content. - Accessibilité RGAA 6.1 : alternative textuelle accessible sur g2rd-map (screen-reader-text).
- Accessibilité RGAA 12.1 :
aria-labelsur les liens icône-seule de g2rd-icon-box. - Accessibilité RGAA 4.1 :
aria-controls,aria-live,aria-currentsur g2rd-slider.
- Bloc : nouveau bloc G2RD Pin Scroll — séquence d'images synchronisée au défilement (style Apple), verrouillé derrière licence + feature toggle.
- Accessibilité : refonte complète du panneau d'accessibilité flottant — localStorage, aria-live, icônes distinctes, profils rapides (Dyslexie, Basse vision, Anti-mouvement), reset, mobile-responsive.
- RGAA : intégration de
inc/rgaa-accessibility.phpdirectement dans le thème (8 correctifs : aria-label réseaux sociaux, lire la suite, privacy, formulaires Fluent Forms, skip-link, images décoratives). - Dark mode : isolation CSS Fluent Community — les blocs code de Fluent Community ne sont plus impactés par le dark mode du thème.
- Fix :
overflow-x: clipsur.g2rd-magic-page(RGAA 10.4 — zoom 200% sans troncature horizontale).
- Fix (RGAA 10.4) : remplacement de
overflow: hiddenparoverflow-x: clipsur.g2rd-magic-pageet.g2rd-magic-dark— le contenu textuel n'est plus tronqué au zoom navigateur 200%.
- Accessibilité (RGAA 6.1) : champs
aria-labeléditables ajoutés sur les blocs g2rd-card, g2rd-hero, g2rd-cta-band, g2rd-pricing-table et g2rd-filterable-grid pour rendre explicites les liens au texte ambigu. - Accessibilité (RGAA 3.2) : contraste des couleurs
mutedetneutral-500corrigé — ratio ≥ 4.59:1 sur fond crème (WCAG AA). - Accessibilité (RGAA 1.1) : attributs
altde substitution ajoutés aux patternssection-temoignages(3 avatars) etcard-info-box(icône). - Updater : lien "Afficher les détails de la version" ajouté sur la page Mises à jour WordPress pour le thème G2RD.
- Fix : résolution vulnérabilité
basic-ftp(npm audit fix).
- Feature : édition inline RichText sur 7 blocs (g2rd-cta-band, g2rd-hero, g2rd-card, g2rd-advanced-heading, g2rd-geo-summary, g2rd-pricing-table, g2rd-geo-faq) — le contenu textuel s'édite directement sur le canvas sans passer par la sidebar.
- Feature : nouveau bloc
g2rd/effect-kitsenregistré — support dansBlockEditorAutoload(localisation licence éditeur) et dans la page d'options. - Fix :
aria-hidden="true"ajouté sur les icônes Dashicons décoratives dans g2rd-card, g2rd-info et g2rd-counter. - Fix : g2rd-carousel — fallback
altsur les images de carrousel (captionsialtvide). - Fix : g2rd-pricing-table
render.php—wp_kses_postremplaceesc_htmlpourctaTextetbadge(support HTML RichText).
- Feature : lien « Voir les détails de la version X.Y.Z » dans la notification de MAJ WordPress — ouvre un modal Thickbox avec le changelog formaté depuis la release GitHub.
- Fix :
getThemeInforetourne désormais un objet stdClass (attendu partheme-install.php).
- Fix : groupe cliquable —
next_tag()sans filtre de classe (robuste en WP 6.6+) ;cursor:pointerinjecté viawp_headindépendamment du JS ; navigation viawindow.location.hrefau lieu delink.click().
- Fix : groupe cliquable — regex remplacé par
WP_HTML_Tag_Processor(WP 6.2+) pour compatibilité fiable avec les structures de blocs WordPress 6.6+ (classes layout multiples, inner container). - Fix : CSS manquant en navigation privée — suppression du
defer_non_critical_cssdansPerformanceCSS(conflit aveccss_async.min.jsde LiteSpeed Cache en cache froid).
- Fix : groupe cliquable —
readyStatecheck remplaceDOMContentLoadedpour compatibilité LiteSpeed Cache (callback ne se déclenchait jamais si LiteSpeed avait déjà exécuté le DOM) ;cursor: pointerajouté sur le groupe activé ;clickable-articles.jsexclu de l'optimisation LiteSpeed.
- Performance : CSS critique inliné dans
<head>viaPerformanceCSS— footer et micro-interactions chargés en différé (amélioration FCP/LCP). - Performance :
font-display: swapsur les 8 polices du thème — texte visible pendant le chargement des polices (amélioration FCP). - Performance : lazy loading intelligent via
PerformanceImages— première image eneager/fetchpriority=high, reste enlazy/decoding=asyncavec dimensions explicites (amélioration CLS/LCP). - Performance : preload de l'image hero dans
<head>viaparse_blocks()(amélioration LCP). - Performance : détection WebP automatique via
wp_content_img_tag— swap vers.webpsi disponible sur le serveur. - Performance : suppression
feed_links_extraet déqueue conditionnel decomment-reply(réduction TBT). - Performance : cache transients centralisé via
PerformanceCache— CSS critique 24h, JSON-LD 12h, invalidation automatique surswitch_theme/save_post. - Performance :
PerformanceAudit— log WP_DEBUG : SQL, styles, scripts et taille HTML par page. - Fix : suppression des preload GSAP CDN qui causaient des warnings console « preloaded but not used within a few seconds ».
- Fix : bloc Google Reviews — cache stale permanent (fallback sur dernières données connues si API en erreur ou clé manquante).
- Style : composants page prestation intégrés dans
magic-page.css— supprime le CSS inline Gutenberg des<!-- wp:html -->.
- Fix FAQ GEO : mode
<details>/<summary>—allowMultiplefonctionnel sur le frontend via événementtogglenatif ; masquage du marqueur<summary>dans Firefox, Chrome et Safari (list-style: none+::marker { content: none }). - Perf : suppression de
wp-embed.min.jssur toutes les pages frontend — script oEmbed inutile sur un site vitrine (~3 KB JS évités). - Perf : déqueue automatique des assets frontend des plugins admin-only (Hostinger AI, ManageWP Worker, Fluent Boards, Fluent Security, Fluent Messaging, Loco Translate) via
ScriptsManager::dequeuePluginAssets(); filtreg2rd_dequeue_plugin_handlespour personnalisation. - Perf : blocs Counter, Typed, FAQ migrés de
"script"vers"viewScript"— leurs scripts ne chargent plus dans le canvas Gutenberg (éditeur plus léger), le frontend est inchangé.
- Sécurité : chargement dynamique des classes renforcé —
realpath(),basename(),str_starts_with()+ confinement au répertoireclasses/. - Fix FAQ : overflow corrigé éditeur/frontend + option
allowMultipleaccordéon fonctionnelle dans le canvas Gutenberg. - CI : correction des faux positifs PHPCS Security sur les
require_oncedynamiques. - Dépendances :
npm audit fixaxios high severity.
- Sécurité : validation
accentColoravant injection dansdangerouslySetInnerHTMLdu bloc Hero — protection XSS sur l'attribut style. - Sécurité : strip
<script>surprice_htmldans filterable-grid/view.js — défense en profondeur sur l'HTML WooCommerce/FluentCart. - Fix : memory leak
setTimeoutdansTabLicence.js—clearTimeoutajouté à l'unmount viauseRef+useEffect. - Perf :
cardOptsetcardColorsmémorisés avecuseMemodans filterable-grid/edit.js — re-renders inutiles des cartes éliminés. - Fix :
openIndexde l'accordéon FAQ resynchronisé avec l'attributopenFirstviauseEffect. - Refactor :
TabLicence.jsmigré de 6useStateversuseReducer— transitions d'état déterministes. - UX :
window.confirm()remplacé par<ConfirmDialog>WordPress dans l'onglet Licence. - Refactor : 40
require_oncestatiques remplacés par un glob dynamique avec ordre de priorité dansfunctions.php. - Feat : setup Playwright E2E — config,
.env.example, specs hero/carousel/faq, CI optionnel. - Docs : design system complet — tokens, blocs, patterns, features, page Gutenberg.
- Chore : normalisation des noms de dossiers de blocs en kebab-case (
g2rd-*).
- Fix dark mode : couverture complète de tous les blocs (Testimonial, FilterableGrid, Modal, Counter, Carousel, Countdown, GEO Summary, FAQ, Toggle Content, Slider, Header).
- Fix : synchronisation cookie/localStorage corrigée — le dark mode PHP (body class) restait actif après désactivation JS.
- Fix a11y : contrastes WCAG 2.1 corrigés en dark mode —
contrast-3#9e9e9e (6.99:1 AA), liens #7cb4f5 (5.5:1 AA), FAQ accent secondaire gold (7.37:1 AAA), GEO Summary tagline/bullet (7.37:1 AAA).
- Fix : Table des matières — cache-buster
view.asset.phpmis à jour pour forcer le rechargement du JS corrigé (hash identique = ancien fichier servi par LiteSpeed/navigateur).
- Fix : Table des matières — priorité du sélecteur corrigée, seuls les titres du contenu de l'article (
.wp-block-post-content) sont indexés, plus les titres de la page entière.
- Perf : Plus Jakarta Sans —
fontDisplay: swap+ preload déclaré en<head>(police découverte à 334ms dans la chaîne critique). - Perf :
fetchpriority="high"automatique sur la première image LCP des templates FSE (suppression du délai d'affichage élément). - Perf : stratégie
deferappliquée automatiquement à tous lesviewScriptdes blocs g2rd (suppression du render-blocking sur LCP/FCP).
- Feat : Agent Discovery — WebMCP (
navigator.modelContext.provideContext()), Agent Skills index (/.well-known/agent-skills/index.json), MCP Server Card (/.well-known/mcp/server-card.json), Link headers RFC 8288 pour la compatibilité agents IA. - Fix : page de connexion WordPress — responsive mobile/tablette corrigé (media queries injectées dans le CSS inline après les règles dynamiques).
- Testimonial : nouveau toggle "Lien vers Google Business" — la barre de note globale (logo Google + étoiles + nombre d'avis) devient un lien cliquable vers la fiche Google Maps, activable dans le panneau du bloc, sans saisie manuelle d'URL.
- GoogleReviews API : champ
urlajouté aux fields Places API → exposé enplace_urldans la réponse REST et inclus dans le cache transient 12h.
- Templates : redesign complet des 21 templates FSE — heroes bleubeige gradient, barres de stats navy, sections cream, CTA bands cohérents sur toutes les pages (page-accueil, page-agence, page-artisan, page-vtc, page-ecommerce, page-contact, page-landing, page-services, page.html, single.html, archive.html, search.html, 404.html, single/archive CPT portfolio/prestations/qui-sommes-nous, taxonomy-site_web).
- CSS :
assets/css/header.css+assets/css/footer.css— styles du header dark/light et du footer glassmorphism extraits dans des fichiers CSS dédiés (separation of concerns, maintenance facilitée). - ScriptsManager : enqueue global de
g2rd-headeretg2rd-footersur toutes les pages frontend.
- fix : FAQPage JSON-LD en double — les items de tous les blocs FAQ (
g2rd/faqmode GEO etg2rd-geo-faq) sont fusionnés dans un seul<script type="application/ld+json">émis enwp_footer, éliminant l'alerte Google Search Console "Champ FAQPage en double". - fix(CI) :
package.jsonverrouillé à 3 parties (1.7.3) pour compatibilitéverify-release-version.sh.
- fix :
composer.lockresynchronisé — hash de contenu désaligné après la mise à jour deextra.g2rd_theme_versionen 1.7.3, corrigeant l'erreur CIcomposer validate. - docs : CLAUDE.md mis à jour — table des skills disponibles, Magic Page design system, features admin, LiteSpeed compatibility.
- feat : Anti-FOUC dark mode — script inline dans
<head>(priority 1) élimine le flash lumière→sombre avant le rendu. - feat : FSE templates persistants —
wp_optionrésistant aux flush de transients et aux mises à jour ; suppression conservatrice (trash/auto-draft uniquement). - feat : Panneau d'accessibilité contrôlable depuis la page d'options admin (toggle + icône dashicons).
- feat : Magic Page design system —
magic-page.cssconditionnel viastyle_handle, 4 styles de blocs (magic-dark, magic-light, neomorphic, soft-pressed), 2 patterns. - fix : LiteSpeed Cache — filtre
litespeed_optm_js_excexclutdark-mode.js,accessibility.jsetfluent-cartdu defer LiteSpeed. - fix : GSAP preload 404 — URLs CDN Cloudflare corrigées avec
crossorigin="anonymous". - fix :
clickable-articles.js— preload warning supprimé (conflit avec LiteSpeed defer). - perf :
will-change: transformdéplacé sur:hoveruniquement — réduit la saturation GPU sur pages denses. - perf : Scroll listener passif (
{ passive: true }) + throttlerequestAnimationFramedansaccessibility.js.
- Fix : styles du bloc FAQ absents en production —
src/style.cssexclu du ZIP ; compilation webpack versbuild/style-style.css+block.jsonmis à jour.
- Style : redesign frontend bloc FAQ — accordéon "Editorial Lines" avec numéros CSS counter (
01,02…), séparateurs horizontaux, icône cercle animé (fill au survol/ouverture), barre accent gauchescaleY, fade-in + slide des réponses alignées sous le texte question.
- Fix : classmap Composer régénérée — classe
AgentDiscoveryabsente au démarrage du thème. - Fix CI : permissions exécutables (
+x) restaurées survendor/bin/(perte depuis Windows). - Chore :
vendor/dev-dependencies ajoutées (phpunit, phpstan, WPCS, PHPCompatibility) +composer.locksynchronisé.
- Agent Discovery : nouvelle classe
AgentDiscovery— RFC 8288 Link headers (service-desc,api-catalog), endpoint/.well-known/api-catalog(RFC 9727,application/linkset+json), négociation Markdown (Accept: text/markdown), Content Signals dansrobots.txt. - Marquee : support layout (
inherit: false), CSSalignfull/alignwide,box-sizing: border-box. - GEO Summary : déprécié v1 enregistré (migration badge GEO → v2 sans badge), null-safety sur
keyPoints.
- Fix CI : release.yml — hostname MySQL
127.0.0.1au lieu demysql(jobs sans container GitHub Actions).
- Fix CI : verify-theme-zip.sh — herestring
<<<au lieu deecho | greppour éviter EPIPE avecpipefail(fausse erreur "index.php absent du ZIP").
- Fix : semver package.json — versions 4-parties tronquées à 3 pour compatibilité wp-scripts.
- Fix : script verify-release-version.sh — comparaison package.json tolère les versions WordPress 4-parties.
- Fix : alignement des versions (package.json, readme.txt, composer.json) après release 1.7.1.
- Fix : synchronisation composer.lock suite au bump de version.
- Fix CI : PHPStan — config neon, mémoire illimitée, excludePaths optionnels.
- Fix CI : PHPCS — fallback statique sans glob, sync composer.lock, scope security audit.
- Sécurité : override postcss ^8.5.10 (GHSA-qx2v-qp2m-jg93 XSS).
- Autoloader : chargement PSR-4 via Composer avec fallback require_once pour les ZIPs de production sans vendor/.
- Licence : mode dégradé gracieux — blocs existants préservés (inserter désactivé) si licence inactive, au lieu de désinscrire les blocs.
- Éditeur : notice WordPress affichée dans l’éditeur quand la licence est inactive.
- Sécurité : messages d’erreur du gestionnaire de licences masqués en production (détails visibles uniquement avec WP_DEBUG).
- Tests : infrastructure PHPUnit + smoke tests des classes critiques + tests JS blocs Gutenberg.
- CI : release.yml — vérification d’alignement des versions, audit Composer/npm, test d’installation WordPress via wp-cli.
- CI : scripts de vérification ZIP et d’alignement de version (tools/).
- Fix : enqueueLicenseEditorNotice attaché au bon handle wp-dom-ready.
- Fix : python3 remplacé par node dans verify-release-version.sh.
- PHPCS : règles durcies — suppressions globales remplacées par exceptions ciblées par fichier.