Blade Parser

Blade Parser

Blade Compiler

The Blade Parser library provides an independent Blade compiler implementation. This implementation is provided to help facilitate testing of the library itself, as well as to provide a convenient way to implement more advanced validation systems utilizing incremental compilation, where each section of a template can be compiled separately and analyzed.

#Replacing the Core Blade Compiler

Replacing the core Laravel Blade compiler entirely is not recommended, mainly due to the high likelihood of undesirable/unpredictable behavior when interacting with third-party libraries and Laravel itself.

The main issues likely to arise are subtle differences produced by any feature that directly type-hints Laravel's Illuminate\View\Compilers\BladeCompiler class.

However, extreme efforts have been made to ensure the compiler implementation provided by this library has a matching public API. It also emulates the behavior of raw blocks (@__raw_block_0__@) for pre-compilers and extensions.

#Compilation Phases

The provided compiler implementation is designed to be backward compatible with existing pre-compilers and extensions. The compiler utilizes multiple phases to ensure that existing tooling receives standard input and supports the node-based compilation required by the implementation.

The compiler will utilize the following phases to compile a Blade template:

  1. If component tags are present in the node list, they are compiled first. The resulting document will be parsed again by an internal parser instance, and the resulting nodes will be supplied to the following compilation phase.

  2. Suppose pre-compilers have been registered with the compiler. In that case, the template will be transformed, and instances of PHP blocks and verbatim nodes will be replaced with their _raw_block_ equivalents. Once all pre-compilers have been evaluated against the transformed document, the transformation step is reversed, and the resulting template is parsed again. The resulting nodes are then used in the following compilation phase.

  3. If compiler extensions are available, the process from step two essentially repeats. However, at this point, only the non-PHP tag content is supplied to extensions for maximum backward compatibility.

  4. The compiler will check the current error tolerance settings and throw CompilationException exceptions according to those settings if the resulting template contains errors.

  5. The next step in template compilation is to iterate the nodes from the document directly and emit the appropriate result to the output buffer. Custom directives will be prioritized over core directives, and the compiler manages core directive compilation.

  6. Document line endings are adjusted to match the style present in the original template.

  7. Footers are appended to the end of the compiled template, if available.

  8. Echo handler Blade compiler variables are added to the compiled template if available.

  9. Component class placeholders are removed from the compiled output.

  10. The compiled output is returned.

#Configuring the Compiler

The provided compiler implementation works to be independent of the core compiler in many ways. As such, it needs to be taught about components such as namespaces, aliases, custom conditions or directives, etc.

Default Configuration

This section only applies if you are looking to manually construct a compiler instance. By default, the compiler factory and service bindings will keep the compiler instances in sync with the Laravel compiler.

Internally this accomplished using the Stillat\BladeParser\Support\BladeCompilerDetailsFetcher "prybar" class.

The following information is required in order to compile a Blade template successfully:

  • Anonymous component paths

  • Anonymous component namespaces

  • Class component aliases

  • Class component namespaces

  • Precompilers

  • Echo handlers

  • Extensions

  • Conditions

  • Custom directives

#Available Methods

#extend

Register a custom Blade compiler extension.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::extend method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

1<?php
2 
3public function extend(
4 callable $compiler
5): void;

#precompiler

Registers a precompiler with the compiler.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::precompiler method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

Argument

Description

$precompiler

The precompiler.

1<?php
2 
3public function precompiler(
4 callable $precompiler
5): void;

#setEchoFormat

Set the echo format to be used by the compiler.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::setEchoFormat method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

Argument

Description

$format

The format to use.

1<?php
2 
3public function setEchoFormat(
4 string $format
5): void;

#withDoubleEncoding

Set the "echo" format to double encode entities.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::withDoubleEncoding method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

1<?php
2 
3public function withDoubleEncoding(): void;

#withoutDoubleEncoding

Set the "echo" format to not double encode entities.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::withoutDoubleEncoding method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

1<?php
2 
3public function withoutDoubleEncoding(): void;

#include

Register an include alias directive.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::include method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

1<?php
2 
3public function include(string $path,
4 ?string $alias = null): void;

#directive

Registers a handler for custom directives.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::directive method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

Argument

Description

$name

The directive name.

$handler

The handler

1<?php
2 
3public function directive(string $name,
4 callable $handler): void;

#aliasInclude

Register an include alias directive.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::aliasInclude method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

1<?php
2 
3public function aliasInclude(string $path,
4 ?string $alias = null): void;

#if

Register an "if" statement directive.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::if method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

Argument

Description

$name

The condition handler name.

$callback

The condition handler.

1<?php
2 
3public function if(string $name,
4 callable $callback): void;

#registerCustomComponentTagCompiler

Register a custom component tag compiler.

This method will automatically register the provided tag name with the component tag compiler.

Argument

Description

$tagName

The custom component tag prefix.

$compiler

The compiler instance.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4use Stillat\BladeParser\Contracts\CustomComponentTagCompiler;
5 
6public function registerCustomComponentTagCompiler(string $tagName,
7 CustomComponentTagCompiler $compiler): Compiler;

#setCompileCoreComponents

Sets whether to compile core Laravel component tags.

When set to false, the internal component tag compiler will not compile Laravel component tags (<x-, <x:, etc.).

Argument

Description

$compileCoreComponents

Whether to compile core Laravel component tags.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setCompileCoreComponents(
6 bool $compileCoreComponents
7): Compiler;

#aliasComponent

Register a component alias directive.

This method has the same behavior as the Illuminate\View\Compilers\BladeCompiler::aliasComponent method. You do not need to manually call this method to sync compiler information if you use the default compiler factory methods/service bindings.

1<?php
2 
3public function aliasComponent(string $path,
4 ?string $alias = null): void;

#getErrors

Retrieves a collection of all parser errors.

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

#onAppend

Adds a callback that will be invoked after the compiler finishes compiling a node.

The provided callback will be invoked each time the compiler has finished compiling a node, and it has been appended to the internal output buffer. The callback will receive an instance of Stillat\BladeParser\Compiler\AppendState as its first argument.
Callbacks are invoked in the order they were registered.

Argument

Description

$callback

The callback.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function onAppend(
6 callable $callback
7): Compiler;

#getExtensions

Get the extensions used by the compiler.

Retrieves all extensions registered with the compiler via the extend method.

1<?php
2 
3public function getExtensions(): array;

#setFailOnParserErrors

Sets whether the compiler should fail on parser errors.

When set to true, the compiler will throw an instance of Stillat\BladeParser\Errors\Exceptions\CompilationException whenever it encounters a parser error.

Argument

Description

$failOnParserErrors

Whether to fail on parser errors.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setFailOnParserErrors(
6 bool $failOnParserErrors
7): Compiler;

#getFailOnParserErrors

Returns a value indicating if the compiler will fail on parser errors.

1<?php
2 
3public function getFailOnParserErrors(): bool;

#setParserErrorsIsStrict

Sets whether the compiler will fail on any parser error.

When set to true, the compiler will fail on any error type. When set to false, it will only fail on fatal errors.

Argument

Description

$isParserErrorsStrict

Whether to fail on any parser error.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setParserErrorsIsStrict(
6 bool $isParserErrorsStrict
7): Compiler;

#getParserErrorsIsStrict

Returns a value indicating if the compiler will fail on any parser error.

1<?php
2 
3public function getParserErrorsIsStrict(): bool;

#setExtensions

Sets and overrides all compiler extensions.

This method will override any extension that had been previously registered with the extend method.
In default setups, this is set to the return value of Illuminate\View\Compilers\BladeCompiler::getExtensions()

Argument

Description

$extensions

The extensions.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setExtensions(
6 array $extensions
7): Compiler;

#setAnonymousComponentNamespaces

Sets and overrides all anonymous component namespaces.

In default setups, this is set to the return value of Illuminate\View\Compilers\BladeCompiler::getAnonymousComponentNamespaces()

Argument

Description

$anonymousNamespaces

The anonymous namespaces.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setAnonymousComponentNamespaces(
6 array $anonymousNamespaces
7): Compiler;

#setClassComponentAliases

Sets and overrides all class component aliases.

In default setups, this is set to the return value of Illuminate\View\Compilers\BladeCompiler::getClassComponentAliases()

Argument

Description

$aliases

The class component aliases.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setClassComponentAliases(
6 array $aliases
7): Compiler;

#setClassComponentNamespaces

Sets and overrides all class component namespaces.

In default setups, this is set to the return value of Illuminate\View\Compilers\BladeCompiler::getClassComponentNamespaces()

Argument

Description

$namespaces

The class component namespaces.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setClassComponentNamespaces(
6 array $namespaces
7): Compiler;

#setAnonymousComponentPaths

Sets and overrides all anonymous component paths.

In default setups, this is set to the return value of Illuminate\View\Compilers\BladeCompiler::getAnonymousComponentPaths()

Argument

Description

$paths

The anonymous component paths.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setAnonymousComponentPaths(
6 array $paths
7): Compiler;

#setThrowExceptionOnUnknownComponentClass

Sets whether the compiler will fail when it encounters unknown component classes.

Argument

Description

$doThrow

Whether to throw on unknown component classes.

1<?php
2 
3public function setThrowExceptionOnUnknownComponentClass(
4 bool $doThrow
5): void;

#setCompilesComponentTags

Sets whether to compile class component tags.

Argument

Description

$compilesComponentTags

Whether to compile component tags.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setCompilesComponentTags(
6 bool $compilesComponentTags
7): Compiler;

#setCompilationTarget

Sets the internal compilation target.

Argument

Description

$compilationTarget

The compilation target.

1<?php
2 
3use Stillat\BladeParser\Compiler\CompilationTarget;
4use Stillat\BladeParser\Compiler\Compiler;
5 
6public function setCompilationTarget(
7 CompilationTarget $compilationTarget
8): Compiler;

#setConditions

Sets and overrides all custom condition handlers.

In default setups, this is set to the return value of Illuminate\View\Compilers\BladeCompiler::$conditions protected property.

Argument

Description

$conditions

The condition handlers.

1<?php
2 
3use Stillat\BladeParser\Compiler\Compiler;
4 
5public function setConditions(
6 array $conditions
7): Compiler;

#getConditions

Gets all custom condition handlers.

1<?php
2 
3public function getConditions(): array;

#getPrecompilers

Returns the configured precompilers.

1<?php
2 
3public function getPrecompilers(): array;

#setPrecompilers

Sets the internal precompilers.

In default setups, this is set to the value of the Illuminate\View\Compilers\BladeCompiler::$precompilers protected property.

Argument

Description

$precompilers

The precompilers.

1<?php
2 
3public function setPrecompilers(
4 array $precompilers
5): void;

#compileString

Compile the given Blade template contents.

Argument

Description

$template

The template.

1<?php
2 
3public function compileString(
4 string $template
5): string;

#setEchoHandlers

Sets and overrides all existing echo handlers.

In default setups, this is set to the value of the Illuminate\View\Compilers\BladeCompiler::$echoHandlers protected property.

Argument

Description

$handlers

The echo handlers.

1<?php
2 
3public function setEchoHandlers(
4 array $handlers
5): void;

#getEchoHandlers

Returns all configured echo handlers.

1<?php
2 
3public function getEchoHandlers(): array;

#getCustomDirectives

Get the list of custom directives.

1<?php
2 
3public function getCustomDirectives(): array;

#getFirstError

Retrieves the first error.

If the error source contains multiple types of errors, such as parser errors and validation errors, all errors will be considered.

1<?php
2 
3use Stillat\BladeParser\Errors\BladeError;
4 
5public function getFirstError(): BladeError;

#getFirstFatalError

Retrieves the first fatal error.

If the error source contains multiple types of errors, such as parser errors and validation errors, all errors will be considered. Fatal errors are considered those that would produce invalid compiled PHP code, regardless of which compiler implementation is used.

1<?php
2 
3use Stillat\BladeParser\Errors\BladeError;
4 
5public function getFirstFatalError(): BladeError;

#hasErrors

Tests if any errors are present.

1<?php
2 
3public function hasErrors(): bool;

#hasFatalErrors

Tests if any fatal errors are present.

1<?php
2 
3public function hasFatalErrors(): bool;

#hasErrorOnLine

Tests if an error matching the provided properties exists on a specific line.

Argument

Description

$line

The line to check.

$type

The error type to check for.

$context

The error context.

1<?php
2 
3use Stillat\BladeParser\Errors\ErrorType;
4 
5public function hasErrorOnLine(int $line,
6 ErrorType $type,
7 ConstructContext $context): bool;

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.