Blade Parser

Blade Parser

Document Structures

While there are many Blade directive "pairs," such as the conditions, stacks, and related, Blade is inherently a structureless templating language. However, the Blade Parser library can make sense of structures within a Blade template to help tool makers make decisions based on what types of things appear in a document.

The library does this by making a few assumptions. The first assumption is that if a directive name also has a corresponding directive name that appears with the word end, those can be paired together.

In the following example, we create two custom directives. The second directive name is the same as the first but is prefixed with end. After performing structural analysis, we can retrieve the first directive and access its closing directive like so:

1<?php
2 
3use Illuminate\Support\Facades\Blade;
4use Stillat\BladeParser\Document\Document;
5 
6Blade::directive('custom', fn() => 'test');
7Blade::directive('endCustom', fn() => 'test');
8 
9$template = <<<'BLADE'
10 @custom
11 
12 @endCustom
13BLADE;
14 
15$doc = Document::fromText($template)
16 ->resolveStructures();
17 
18// Returns "endCustom"
19$doc->findDirectiveByName('custom')
20 ->isClosedBy->content;

The pairing algorithm will attempt to pair the closest directives together where possible. In the following example, the first instance of the custom directive will not be paired with anything, but the second one will:

1use Illuminate\Support\Facades\Blade;
2use Stillat\BladeParser\Document\Document;
3 
4Blade::directive('custom', fn() => 'test');
5Blade::directive('endCustom', fn() => 'test');
6 
7$template = <<<'BLADE'
8 {{-- This is not paired. --}}
9 @custom
10 
11 {{-- But this is. --}}
12 @custom
13 
14 @endCustom
15BLADE;
16 
17$doc = Document::fromText($template)
18 ->resolveStructures();
19 
20// Returns "endCustom"
21$doc->findDirectivesByName('custom')[1]
22 ->isClosedBy->content;

Structures like the forelse block, conditions, and switch statements are all managed by separate, dedicated analyzers. In the case of conditions, the library will consider any custom Blade conditions or any core directive that can be used as a condition. Each structure type will produce a specialized structure instance that offers more information about its usage within the document.

Some structures, such as raw PHP blocks and verbatim regions, do not require structural analysis. These structures are handled directly by the document parser.

#Available Methods

#resolveStructures

Resolves structures within the document, such as directive pairs.

Structural analysis can only be performed once on a Document instance. If changes have been made to the node structure, you are encouraged to call the toDocument() method to construct a new document.

1<?php
2 
3use Stillat\BladeParser\Document\Document;
4 
5public function resolveStructures(): Document;

#getAllStructures

Returns all the document structures.

This method automatically performs structural analysis on the document.

1<?php
2 
3use Illuminate\Support\Collection;
4 
5public function getAllStructures(): Collection;

Example Use

1<?php
2 
3use Stillat\BladeParser\Document\Document;
4 
5$template = <<<'BLADE'
6 @if ($varOne)
7 @if ($varTwo)
8 
9 @endif
10 @endif
11BLADE;
12 
13$doc = Document::fromText($template);
14 
15// Returns 2
16$afterCount = $doc->getAllStructures()->count();

#getRootStructures

Returns the direct document structures.

This method automatically performs structural analysis. Only structures that are at the root of the document, without any parent node, will be returned.

1<?php
2 
3use Illuminate\Support\Collection;
4 
5public function getRootStructures(): Collection;

#getAllSwitchStatements

Returns all the document's switch statements.

This method automatically performs structural analysis.

1<?php
2 
3use Illuminate\Support\Collection;
4 
5public function getAllSwitchStatements(): Collection;

Example Use

1<?php
2 
3use Stillat\BladeParser\Document\Document;
4 
5$template = <<<'BLADE'
6 @switch ($var)
7 @case (1)
8 @switch ($var)
9 @case (1)
10 @break
11 @endswitch
12 @break
13 @endswitch
14BLADE;
15 
16$doc = Document::fromText($template);
17 
18// Returns 2
19$count = $doc->getAllSwitchStatements()->count();

#getRootSwitchStatements

Returns all the direct switch statements.

This method automatically performs structural analysis. Only @switch statements that appear at the root of the document, without any parent nodes, will be returned.

1<?php
2 
3use Illuminate\Support\Collection;
4 
5public function getRootSwitchStatements(): Collection;

#getAllConditions

Returns all the document's conditions.

This method automatically performs structural analysis.

1<?php
2 
3use Illuminate\Support\Collection;
4 
5public function getAllConditions(): Collection;

Example Use

1<?php
2 
3use Stillat\BladeParser\Document\Document;
4 
5$template = <<<'BLADE'
6 @if ($condition)
7 @if ($condition)
8 
9 @endif
10 @endif
11BLADE;
12 
13$doc = Document::fromText($template);
14 
15// Returns 2
16$count = $doc->getAllConditions()->count();

#getRootConditions

Returns all the document's root conditions.

This method automatically performs structural analysis. Only structures that appear at the root of the document, without any parent node, will be returned.

1<?php
2 
3use Illuminate\Support\Collection;
4 
5public function getRootConditions(): Collection;

#getAllForElse

Returns all the document's for-else blocks.

This method automatically performs structural analysis.

1<?php
2 
3use Illuminate\Support\Collection;
4 
5public function getAllForElse(): Collection;

Example Use

1<?php
2 
3use Stillat\BladeParser\Document\Document;
4 
5$template = <<<'BLADE'
6 @forelse ($users as $user)
7 
8 @forelse ($tasks as $task)
9 
10 @empty
11 
12 @endforelse
13 
14 @empty
15 
16 @endforelse
17BLADE;
18 
19$doc = Document::fromText($template);
20 
21// Returns 2
22$count = $doc->getAllForElse()->count();

#getRootForElse

Returns the direct for-else blocks.

This method automatically performs structural analysis. Only nodes that appear at the root of the document, without any parent nodes, will be returned.

1<?php
2 
3use Illuminate\Support\Collection;
4 
5public function getRootForElse(): Collection;

Some absolutely amazing
people

The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.