What Is Forte?
Forte (fortephp/forte) is a Laravel package written by John Koster that parses .blade.php files into a typed syntax tree. Instead of running a regex or a sed one-liner that blindly matches every occurrence — including ones inside comments, strings, and unrelated attributes — Forte gives you a structured document you can query and rewrite with precision.
Version 3 of prettier-plugin-blade (Chisel) is built on Forte, and the project reports it formats complex real-world templates 140 times faster than the previous version.
Installation
Forte requires PHP 8.2, the ext-dom extension, and Laravel 10–13:
composer require fortephp/forte
The service provider auto-registers, so the Forte facade is available immediately.
Parsing Blade Files
use Forte\Facades\Forte;
$doc = Forte::parse('<div class="mt-4">Hello, {{ $name }}!</div>');
$doc = Forte::parseFile('resources/views/welcome.blade.php');
Both methods run a lexer and a tree builder. If a template has an unclosed tag or an @if with no @endif, the parser records a diagnostic and returns a partial tree — the other files in your project still parse normally. Rendering a parsed file back without changes produces identical bytes, whitespace included.
Querying the Tree
Query methods return lazy Laravel collections:
$forms = $doc->queryElements('form');
$conditionals = $doc->queryBlockDirectives(['if', 'unless']);
$components = $doc->queryComponents(['x-alert', 'livewire:*']);
Forte builds a DOMDocument internally and exposes XPath queries. Blade constructs become elements in a forte namespace, so @if is forte:if and {{ }} echoes are forte:echo:
$divs = $doc->xpath('//div[@class]')->get();
$conditionals = $doc->xpath('//forte:if')->get();
Matches come back as Forte nodes, not raw DOMElement objects, so you can pipe them straight into a rewrite.
Rewriting Templates
rewriteWith() accepts a closure that receives a NodePath — an object that exposes the node's parent, siblings, ancestors, depth, and mutation methods:
use Forte\Rewriting\NodePath;
$newDoc = $doc->rewriteWith(function (NodePath $path) {
if ($path->isTag('a') && str_starts_with($path->getAttribute('href') ?? '', 'http')) {
$path->setAttribute('target', '_blank');
$path->setAttribute('rel', 'noopener noreferrer');
}
});
echo $newDoc->render();
Edits are queued and applied in a single pass, so a large template produces one new document rather than one per mutation. For longer logic, write a Visitor class with enter() and leave() methods. A Builder helper creates new nodes to insert:
use Forte\Rewriting\Builders\Builder;
Builder::element('div')->class('wrapper')->text('Hello');
Builder::directive('if', '($show)');
Practical Use Cases
Auditing Views Before Deleting a Component
$uses = Forte::parseFile($file->getPathname())
->queryComponents(['x-alert'])
->count();
Unlike grep, this count excludes mentions inside comments, @php strings, and unrelated class attributes.
Bulk Codemods
Adding loading="lazy" to every <img> without that attribute across hundreds of views is a single rewriteWith() pass. An <img> inside a comment parses as a different node kind, so isTag('img') is false for it — no accidental matches.
CI Convention Checks
$missing = Forte::parseFile($file->getPathname())
->xpath('//form[@method="POST"][not(.//forte:csrf)]')
->count();
That XPath expression finds every POST form with no @csrf anywhere inside it. Drop it in a Pest or PHPUnit test to fail the build automatically.
Ecosystem: Chisel and Reload
- Chisel (
prettier-plugin-bladev3) — Blade formatter built on Forte; requires Node 18+. - Reload (
fortephp/reload) — experimental Vite plugin that patches Blade changes into the page without a full refresh, falling back after a configurable number of incremental patches.
Key Takeaways
- Forte parses Blade into a typed syntax tree, avoiding false positives that plague regex-based tools.
- XPath queries use a
forte:namespace for Blade-specific constructs (forte:if,forte:echo,forte:csrf, etc.). - Rewrites are non-destructive:
rewriteWith()returns a newDocumentand leaves the original intact. - Partial parse results and diagnostics mean one broken template never blocks the rest of your codebase.
- Best suited for structure-dependent rules, large-scale codemods, and automated CI checks — not for one-off renames where
sedis faster.
Forte is MIT licensed and currently at v1.1.0. Source and docs: fortephp.com | GitHub.
Source: Forte: Parse and Rewrite Laravel Blade Templates — Laravel News