stillat/blade-parser
Parse, analyze, and transform Laravel Blade templates with a robust PHP parser. stillat/blade-parser provides an AST, tokenization, and utilities to inspect directives, components, and expressions—ideal for linters, formatters, editors, and automated refactoring tools.
Full Changelog: https://github.com/Stillat/blade-parser/compare/v2.0.0...v2.1.0
8.2.0composer.json - thanks @vintagesucks !This release adds a few new helper methods:
toDocument() on DocumentParser simplifies the process of converting an existing DocumentParser to a Document instance
toDocument will resolve structures on the document by default. To prevent this, simply supply false when calling (i.e., toDocument(false))parseTemplate on DocumentParser parses the input like the existing parse method, but will return the DocumentParser instance instead of a node arrayAttributeCompilerThe AttributeCompiler is a new compiler service that can be used to compile attributes/parameters on a parsed ComponentNode. The AttributeCompiler implementation will use the core Laravel compiler for content that contains interpolated values.
Usage:
<?php
use Stillat\BladeParser\Parser\DocumentParser;
use Stillat\BladeParser\Compiler\CompilerServices\AttributeCompiler;
$template = <<<'TEMPLATE'
<prefix:component
parameter="content"
:binding="$theVariable"
/>
TEMPLATE;
$params = (new DocumentParser)
->onlyParseComponents()
->registerCustomComponentTags(['prefix'])
->parseTemplate($template)
->toDocument()
->getComponents()
->first()
->parameters;
$compiler = new AttributeCompiler;
$result = $compiler->compile($params);
After compilation, $result would contain the following:
['parameter'=>'content','binding'=>$theVariable]
EchoNode
EchoNode::isRaw(), EchoNode::isTriple(), and EchoNode::isRegular()[@parent](https://github.com/parent) directive. Thanks @ernix 🥳This release improves the out-of-box experience with the document validator:
In addition, this PR makes the following changes:
ignore_directives validation configuration option will now be used to disable parsing and compilation across all validators, for consistency (#25)[@use](https://github.com/use) directiveUpdate PHP version constraint to match language features used
This release improves the built-in compiler's support for complicated PHP expressions within the [@json](https://github.com/json) directive.
Additionally, this release adds a new abstract node transformer. This transformer provides a simple way to iterate all nodes in a document and change the output, while skipping over nodes within the document.
For example, if we had the following node transformer implementation:
<?php
use Stillat\BladeParser\Compiler\Transformers\NodeTransformer;
use Stillat\BladeParser\Nodes\DirectiveNode;
class CustomTransformer extends NodeTransformer
{
public function transformNode($node): ?string
{
if (! $node instanceof DirectiveNode || $node->content != 'custom') {
return null;
}
$this->skipToNode($node->isClosedBy);
return '[@include](https://github.com/include)("something-here")';
}
}
we could transform a document like so:
<?php
use Stillat\BladeParser\Document\Document;
use Stillat\BladeParser\Document\DocumentOptions;
$doc = Document::fromText($template, documentOptions: new DocumentOptions(
withCoreDirectives: false,
customDirectives: ['custom', 'endcustom']
))->resolveStructures();
$result = (new CustomTransformer())->transformDocument($doc);
to produce the final result:
The beginning.
[@include](https://github.com/include)("something-here")
The end.
This release adds support for compiling name attributes on named slots:
<x-input-with-slot>
<x-slot class="text-input-lg" name="the_slot_name" data-test="data">Test</x-slot>
</x-input-with-slot>
Additionally, we can now easily fetch either a ParameterNode or the slot's string name via. some new utility methods:
<?php
use Stillat\BladeParser\Document\Document;
$template = <<<'BLADE'
<x-input-with-slot>
<x-slot class="text-input-lg" name="the_slot_name" data-test="data">Test</x-slot:input>
</x-input-with-slot>
BLADE;
$doc = Document::fromText($template);
$slot = $doc->findComponentByTagName('slot');
// getName() will return a ParameterNode
// in this scenario, allowing us to
// get additional information.
$slot->getName()->value;
This release adds a new getArgValues helper method to the ArgumentGroupNode node. This is similar to the existing getValues() utility method, but is smarter about how it breaks argument strings:
<?php
use Stillat\BladeParser\Document\Document;
use Stillat\BladeParser\Document\DocumentCompilerOptions;
$template = <<<'BLADE'
[@js](https://github.com/js)(["one, two", $var1, $var2], $hello, 12345.23, bar, baz, (1,2,3,4,), "foo, bar, baz")
BLADE;
$doc = Document::fromText($template);
// Smartly split the argument string.
$doc->findDirectiveByName('js')
->arguments->getArgValues();
The above sample would produce output similar to the following:
Illuminate\Support\Collection {#2538
all: [
"["one, two", $var1, $var2]",
"$hello",
"12345.23",
"bar",
"baz",
"(1,2,3,4,)",
""foo, bar, baz"",
],
}
This release introduces a new onlyParseComponents method to the DocumentParser class, allowing users to only parse components within an input template:
<?php
use Stillat\BladeParser\Parser\DocumentParser;
use Stillat\BladeParser\Document\Document;
$parser = new DocumentParser;
$template = <<<'BLADE'
<x-alert>
{{ $title }} [@if](https://github.com/if) ($this) [@endif](https://github.com/endif)
</x-alert>
BLADE;
// Only the components are parsed.
$parser->onlyParseComponents()->parse($template);
// To construct a Document instance and resolve tag pairs, we may use `syncFromParser`
$document = new Document;
$document->syncFromParser($parser)->resolveStructures();
This release adds a new getValues() method to the Stillat\BladeParser\Nodes\ArgumentGroupNode node, making it easier to work with individual argument strings supplied to directives:
<?php
use Stillat\BladeParser\Document\Document;
$template = <<<'BLADE'
[@extends](https://github.com/extends)("layout")
[@section](https://github.com/section)("content")
[@lang](https://github.com/lang)("arg1")
[@endsection](https://github.com/endsection)
BLADE;
$doc = Document::fromText($template);
$lang = $doc->findDirectiveByName('lang');
// Returns a Collection instance.
$args = $lang->arguments->getValues();
// Returns "arg1"
$value = $args[0];
BladeCompiler to be safer, and provide "future" defaults when the properties/methods don't exist on the current version (#8 )Finally hit version one! 🎉
Initial tag for packagist
How can I help you explore Laravel packages today?