Blade Parser

Blade Parser

Formatter Configuration and Usage

The Prettier Blade plugin supports many different configuration options. These options can be set my creating a new file at the root of your project (yes, another dot file, I'm sorry) called .blade.format.json. This file should exist at the root of your project, next to your composer.json file in a typical Laravel application.

The remainder of this article will assume this file exists.

#Configuring Laravel Pint

The Blade formatter is capable of using Laravel Pint to format PHP code inside your Blade directives, as well as in raw PHP blocks. You will need to have Laravel Pint available globally, or available within your project's vendor folder.

In .blade.format.json

1{
2 "useLaravelPint": true
3}

By default the Blade formatter will look for Pint at the following location:

1project_root/vendor/bin/pint

If you want to customize the Pint command, you can add a pintCommand configuration option to your .blade.format.json configuration file.

In .blade.format.json

1{
2 "useLaravelPint": true,
3 "pintCommand": "your-pint-command {file}"
4}

Make sure to include the {file} as part of your custom command, as the Blade formatter will supply the path to a temporary path it using when invoking Pint. This path will already be wrapped in double quotes - do not add these yourself. Do not include anything after the {file} part of the command. The Blade formatter will merge your Pint configuration (if available) with some internal settings that must be present for safe output.

The Blade formatter does not check what exactly it is you have added to the pintCommand configuration option. If you add some really dumb shell commands, it will attempt to run those.

#Pint Result Cache

The Blade formatter will cache Pint output on a per-file basis. By default this cache is stored in node_modules/prettier-plugin-blade/_cache.

The location of the cache can be changed by updating the .blade.format.json file and specifying a path for the pintCacheDirectory:

In .blade.format.json

1{
2 "useLaravelPint": true,
3 "pintCacheDirectory": "../directory/"
4}

The cache may also be disabled entirely by setting the pintCacheEnabled value to false:

In .blade.format.json

1{
2 "useLaravelPint": true,
3 "pintCacheEnabled": false
4}

#Pint Temporary Directory

The Blade formatter will extract the relevant PHP from Blade templates and place them in a temporary file to supply to Laravel Pint. By default this directory is located at node_modules/prettier-plugin-blade/_temp.

Temporary files are automatically cleaned up after formatting each Blade template. However, if you would like to move this temporary directory you may specify a value for the pintTempDirectory configuration option within your .blade.format.json file:

In .blade.format.json

1{
2 "useLaravelPint": true,
3 "pintCacheDirectory": "../path/"
4}

#Ignoring Parts of a Template

Entire sections of a Blade template can be ignored by surrounding it with two special comments:

1<div>
2{{-- format-ignore-start --}}
3 The template code inside this section will be ignored when formatting.
4{{-- format-ignore-end --}}
5</div>

#Class String Emulation

Class string emulation is a feature (starting with version 1.5) that is able to apply the results of prettier plugins that target CSS class lists to strings contained within Blade directives and embedded PHP code. This feature also works when using Laravel Pint as the PHP formatter.

This feature is enabled by default, with a sensible (and safe) default configuration. If you'd like to disable this feature entirely, you may add a classStrings configuration object to your .blade.format.json file and set the enabled value to false:

In .blade.format.json

1{
2 "classStrings": {
3 "enabled": false
4 }
5}

#Excluding Directives from Class String Emulation

By default, the Blade formatter will not apply class string emulation feature to the following list of directives:

  • if

  • unless

  • elseif

  • for

  • forelse

  • foreach

If you'd like to modify this list you may add a classStrings configuration object to your .blade.format.json file and modify the excludedDirectives configuration property:

In .blade.format.json

1{
2 "classStrings": {
3 "excludedDirectives": [
4 "if", "unless", "elseif", "for", "forelse", "foreach"
5 ]
6 }
7}

#Avoiding Class String Emulation for Entire Templates

Sometimes you may wish to have the class string emulation feature enabled, but have the ability to not have it evaluate certain documents or templates. To help with this, you may set up a list of exclusion regular expressions that will be used to reject a template.

In .blade.format.json

1{
2 "classStrings": {
3 "documentRules": {
4 "excludeWhen": [
5 "skip"
6 ]
7 }
8 }
9}

Each regular expression in the list will be tested against the document before it is evaluated. If any of the exclusion patterns pass, the template will not have class string emulation applied to Blade directives or embedded PHP content.

If you need to do the opposite, and only run the feature on documents that do match a certain pattern, you may alternatively use the includeWhen option:

In .blade.format.json

1{
2 "classStrings": {
3 "documentRules": {
4 "includeWhen": [
5 
6 ]
7 }
8 }
9}

#Specifying String Rules

Similar to excluding or including entire documents, you may also set up a list of rules that are applied to each string. For example, if we only wanted to run the feature on Blade directive or PHP strings that contain the value !tw, we could set up our .blade.format.json file like so:

In .blade.format.json

1{
2 "classStrings": {
3 "stringRules": {
4 "includeWhen": [
5 "!tw"
6 ]
7 }
8 }
9}

#Class String Emulation and PHP Language Features

By default, class string emulation will not be applied to strings under a wide variety of situations. For example, if the string is contained with a condition statement, used in a comparison operation, or is the target of most assignments, the string will not be changed.

For example, the strings in the following template would not be impacted:

1 
2@php
3 
4 if ($someValue == 'text-white px-4 sm:px-8 py-2') {
5 
6 }
7 
8@endphp

If you really want to override this behavior (you probably don't need or want to), you can adjust this behavior by updating the .blade.format.json file and adding a ignoredLanguageStructures configuration property:

Important: If you override this value, you must include all of the structures you would like ignored.

In .blade.format.json

1{
2 "classStrings": {
3 "ignoredLanguageStructures": [
4 "assign",
5 "concat",
6 ...
7 ]
8 }
9}

The following table lists the available configuration options:

PHP Operator/Structure

Configuration String

Ignored by Default

If Statements

if

Yes

Method/Function Calls

call

Yes*

Ternary

ternary

Yes

Addition

addition

Yes

Subtraction

subtraction

Yes

Multiplication

multiplication

Yes

Division

division

Yes

Modulus

modulus

Yes

Exponentiation

exponentiation

Yes

Generic Comparison (if a more specific language structure was not matched)

compare

Yes

Concatenation

concat

Yes

Greater Than

greater_than

Yes

Greater Than or Equal

greater_than_equal

Yes

Less Than

less_than

Yes

Less Than or Equal

less_than_equal

Yes

Bitwise AND

bitwise_and

Yes

Bitwise OR

bitwise_or

Yes

Bitwise XOR

bitwise_xor

Yes

Left Shift

left_shift

Yes

Right Shift

right_shift

Yes

Equality

equality

Yes

Inequality

inequality

Yes

Not Identity

not_identity

Yes

AND Comparison (&&, and, etc.)

and

Yes

OR Comparison (||, or, etc.)

or

Yes

XOR

xor

Yes

Assignment

assign

No

Addition Assignment

assign_addition

Yes

Subtraction Assignment

assign_subtraction

Yes

Multiplication Assignment

assign_multiplication

Yes

Division Assignment

assign_division

Yes

Modulus Assignment

assign_modulus

Yes

Concatenation Assignment

assign_concat

Yes

Bitwise AND Assignment

assign_bitwise_and

Yes

Bitwise OR Assignment

assign_bitwise_or

Yes

Bitwise XOR Assignment

assign_bitwise_xor

Yes

Left Shift Assignment

assign_left_shift

Yes

Right Shift Assignment

assign_right_shift

Yes

* By default the Blade Formatter will allow processing of strings contained within any method named class. You can change this behavior by adding a allowedMethodNames configuration item to the classStrings configuration within your .blade.format.json file:

In .blade.format.json

1{
2 "classStrings": {
3 "allowedMethodNames": [
4 "class",
5 "methodName",
6 "anotherName"
7 ]
8 }
9}

Method names are case sensitive.

#Ignored Strings

Strings will be ignored if any of the following conditions are met (these behaviors cannot be disabled at this time):

  • The string does not contains a space

  • The string contains newline characters

  • The string contains any of the following characters: ${"'

  • The string contains the , (comma space) character sequence

  • Strings inside {{-- format-ignore-start --}}{{-- format-ignore-end --}} regions will NOT be changed

#Formatting JavaScript Inside Attributes

The Blade formatter will format JavaScript inside Alpine.js directives by default (starting with 1.6.0). This can be disabled by adding a formatJsAttributes configuration item to your .blade.format.json:

In .format.blade.json

1{
2 "formatJsAttributes": false,
3}

If you would like to exclude a list of attributes from being formatted, you may add a list of regular expressions to the .blade.format.json file. By default, it contains the following items:

In .blade.format.json

1{
2 "formatJsAttributes": true,
3 "excludeJsAttributes": [
4 "^v-"
5 ]
6}

If you'd like to expand the list of attributes to be formatted, you may add a list of regular expressions to the .blade.format.json file. By default this list contains the following items:

In .blade.format.json

1{
2 "formatJsAttributes": true,
3 "includeJsAttributes": [
4 "^x-",
5 "^ax-"
6 ]
7}

#Preventing Attribute Content from Being Wrapped in Newlines

Some attribute contents are sensitive to newlines, such as Alpine's x-data. To help address this in a general way, the Blade formatter allows you to configure a safeWrappingJsAttributes configuration property within your .blade.format.json file.

This configuration option contains a list of regular expressions. When an attribute matches an item in this list, the internal formatting behavior will change to prevent newlines from being added to the beginning and end of the formatted attribute's content. This configuration contains the following items by default:

In .blade.format.json

1{
2 "formatJsAttributes": true,
3 "safeWrappingJsAttributes": [
4 "^x-data"
5 ]
6}

#Modifying Prettier JavaScript Options

You can change which prettier options are applied to attribute content by adding a attributeJsOptions configuration object to your .blade.format.json file. For example, to increase the print width and disable the insertion of semicolons, you could add the following:

In .blade.format.json

1{
2 "attributeJsOptions": {
3 "semi": false,
4 "printWidth": 120
5 }
6}

The formatter will override the following settings internally for safety reasons:

  • singleQuote: true

  • quoteProps: preserve

#Configuring the Blade Parser

You may optionally configure the Blade parser by creating a file named .blade.format.json at the root of your project. The options that can be used currently are:

  • customIfs: A list of custom if statements. These provide hints to the parser and teach it how to treat custom ifs it encounters differently. If the parser consistently produces odd results for custom ifs, adding them to this list helps. Most of the time the parser can figure these out on its own, however.

  • ignoreDirectives: A list of directive names the parser should ignore.

  • formatDirectivePhpParameters: Indicates if PHP directive content should be formatted. Default: true

  • formatDirectiveJsonParameters: Indicates if JSON directive parameters should be formatted. Default: true

  • spacesAfterDirective: The number of spaces to add after directive names when they contain parameters. Values can be between 0 and 3. Default: 0

Do not add the leading @ when adding directive names to any of the configuration options. When adding custom if statements, you just need to add the first name (add just "disk" instead of adding "disk" and "elsedisk").

In .blade.format.json

1{
2 "ignoreDirectives": [],
3 "customIfs": [],
4 "formatDirectivePhpParameters": true,
5 "formatDirectiveJsonParameters": true,
6 "formatInsideEcho": true,
7 "spacesAfterDirective": 0,
8 "spacesAfterControlDirective": 1,
9 "echoStyle": "block",
10 "phpOptions": {
11 "phpVersion": "8.0"
12 }
13}

The valid options for the echoStyle option are block (the default) and inline. To illustrate what these options do, lets consider the following Blade template:

1<div
2{{
3 match ($foo) {
4 'foo' => 'foo',
5 default => 'bar',
6 }
7}}
8></div>

With the option inline, the formatted result becomes:

1<div
2 {{ match ($foo) {
3 "foo" => "foo",
4 default => "bar",
5 } }}
6></div>

With the option block, the formatted result is:

1<div
2 {{
3 match ($foo) {
4 "foo" => "foo",
5 default => "bar",
6 }
7 }}
8></div>

#Configuring Prettier PHP Options

By default, PHP version 8.0 is configured when formatting directives, @php blocks, etc. You may change this by adding a phpOptions configuration object within your .blade.format.json file. For example, to change the PHP version, disable single quotes, you could do this:

This section does not apply if you are using the Laravel Pint integration.

In .blade.format.json

1{
2 "ignoreDirectives": [],
3 "customIfs": [],
4 "formatDirectivePhpParameters": true,
5 "formatDirectiveJsonParameters": true,
6 "formatInsideEcho": true,
7 "spacesAfterDirective": 0,
8 "spacesAfterControlDirective": 1,
9 "phpOptions": {
10 "singleQuote": false,
11 "phpVersion": "7.0"
12 }
13}

#Ignoring Potential Directive Names

The following are currently consider control directives: if, elseif, unless, while, foreach, forelse, and for.

The internal formatters will only format PHP and JSON content if their contents are considered to be valid when configured to do so. The formatter will not throw an error, and will simply leave the JSON/PHP content unformatted and continue with the rest of the document.

When configuring the ignoreDirectives option whatever values provided will take precedence over the defaults. By default the parser will ignore the following potential directive names that you may want to add back:

In .blade.format.json

1{
2 "ignoreDirectives": [
3 "media",
4 "charset",
5 "import",
6 "namespace",
7 "supports",
8 "document",
9 "page",
10 "font-face",
11 "keyframes",
12 "viewport",
13 "counter-style",
14 "font-feature-values",
15 "swash",
16 "ornaments",
17 "annotation",
18 "stylistic",
19 "styleset",
20 "character-variant",
21 "font-variant-alternates",
22 "property",
23 "color-profile",
24 "click",
25 "submit",
26 "scroll",
27 "keydown",
28 "keypress",
29 "keyup",
30 "blur",
31 "change",
32 "contextmenu",
33 "copy",
34 "cut",
35 "paste",
36 "dblclick",
37 "drag",
38 "dragend",
39 "dragenter",
40 "dragleave",
41 "dragover",
42 "dragstart",
43 "drop",
44 "focus",
45 "focusin",
46 "focusout",
47 "input",
48 "mousedown",
49 "mouseenter",
50 "mouseleave",
51 "mousemove",
52 "mouseover",
53 "mouseout",
54 "mouseup",
55 "mousewheel",
56 "resize",
57 "select",
58 "touchcancel",
59 "touchend",
60 "touchmove",
61 "touchstart",
62 "wheel"
63 ]
64}

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.