Appliquer la même modification à tous les fichiers Blade d'une application Laravel est plus délicat qu'il n'y paraît. Un sed en une ligne remplace chaque occurrence, y compris celles dans les chaînes, les commentaires et les attributs sans rapport. Forte, écrit par John Koster, analyse les fichiers .blade.php en un arbre syntaxique typé, permet d'interroger cet arbre et de réécrire le template. Koster est aussi l'auteur de prettier-plugin-blade, dont la version 3 repose sur Forte.

terminal
composer require fortephp/forte

Forte exige PHP 8.2, l'extension dom et Laravel 10 à 13. L'installation se fait avec composer require fortephp/forte, et le service provider s'enregistre tout seul. Forte::parse() accepte une chaîne, Forte::parseFile() un chemin ; les deux renvoient un Document. Une balise non fermée ou un @if sans @endif produit un diagnostic et un arbre partiel, qui reste interrogeable et réécrivable. Un document non modifié est rendu à l'identique, espaces compris.

Les méthodes de requête renvoient des collections lazy : queryElements('form'), queryBlockDirectives(['if', 'unless']) et queryComponents(['x-alert', 'livewire:*']) sont les principales entrées, avec des accès directs comme elementById() et hasElement(). Les attributs exposent isDynamic() pour les valeurs liées et attributeTokens('class') pour découper une liste de classes. Forte construit aussi un DOMDocument à partir de l'arbre et exécute les expressions via DOMXPath de PHP. Les constructions Blade sont placées dans un espace de noms forte : les blocs @if deviennent forte:if, les échos forte:echo. Les résultats reviennent sous forme de nœuds Forte, directement utilisables pour une réécriture.

apply(), rewrite() et rewriteWith() renvoient chacun un nouveau Document sans toucher l'original. rewriteWith() prend une closure qui reçoit un NodePath plutôt que le nœud lui-même. NodePath expose parents, frères, ancêtres et profondeur, plus des méthodes comme getAttribute(), setAttribute(), removeAttribute(), addClass(), renameTag(), replaceWith(), remove(), insertBefore() et insertAfter(). skipChildren() et stopTraversal() interrompent le parcours. Les modifications sont mises en file puis appliquées en une seule passe. Les transformations plus longues s'écrivent dans un Visitor avec les hooks enter() et leave() ; un RewriteBuilder couvre la version déclarative : sélection XPath, puis mutations en file. Une classe Builder crée de nouveaux nœuds d'élément, de directive et d'écho.

L'article décrit trois cas pratiques. Audit : parser tous les fichiers de resources/views et compter queryComponents(['x-alert']) pour trouver les usages réels du composant, là où grep compterait aussi les commentaires, les chaînes et des classes comme x-alert-icon. Codemod : une passe rewriteWith() ajoute loading="lazy" à chaque <img> dépourvu de l'attribut sur des centaines de vues, avec git restore comme retour arrière. Contrôle CI : un test Pest fait échouer le build si un formulaire POST n'a pas de @csrf, exprimé en une requête XPath, //form[@method="POST"][not(.//forte:csrf)]. Une seconde expression signale les blocs @foreach dont le premier enfant n'a pas d'attribut wire:key.

L'auteur précise les limites : pour un renommage unique sur trente vues, sed ou la recherche structurelle de l'IDE suffisent. Forte se justifie quand la règle dépend de la structure, quand le diff est trop volumineux pour une relecture manuelle ou quand un contrôle s'exécute à chaque commit.

Deux autres paquets reposent sur Forte. Chisel est prettier-plugin-blade v3 réécrit sur le nouveau parseur, annoncé comme formatant des templates complexes réels 140 fois plus vite que la version précédente ; il faut Node 18 ou plus. Reload est un plugin Vite expérimental qui injecte les changements Blade dans le DOM sans rechargement complet, avec retour à un rechargement total après un nombre configurable de patchs incrémentaux. Forte est sous licence MIT, actuellement en v1.1.0. Le code est sur GitHub, la documentation et un playground interactif sur fortephp.com.