Blade Indenter
A very simple formatter for Laravel 5.8+ Blade templates
This package just indents Blade template lines following very simple rules.
It expects a valid and well-formed code and won't format or validate code nor deal well with instructions on
multiple lines.
Any contribution or feedback is highly welcomed, please feel free to create a pull request or submit a new issue.
Example
Input:
@extends('layout')
@section('title', $title)
@section('content')
<h1>
@if($article->exists)
Edit Article {{ $article->id }}
@php($url = route('articles.update', $article->id))
@else
Create a new Article
@php($url = route('articles.store'))
@endif
</h1>
{!! Form::model($article, ['url' => $url]) !!}
<div id='title-group'>
{!! Form::label('title', 'Title') !!}
{!! Form::text('title') !!}
@error('title')
<p>{{ $message }}</p>
@enderror
</div>
{!! Form::submit('Save') !!}
{!! Form::close() !!}
@endsection
Output:
@extends('layout')
@section('title', $title)
@section('content')
<h1>
@if($article->exists)
Edit Article {{ $article->id }}
@php($url = route('articles.update', $article->id))
@else
Create a new Article
@php($url = route('articles.store'))
@endif
</h1>
{!! Form::model($article, ['url' => $url]) !!}
<div id='title-group'>
{!! Form::label('title', 'Title') !!}
{!! Form::text('title') !!}
@error('title')
<p>{{ $message }}</p>
@enderror
</div>
{!! Form::submit('Save') !!}
{!! Form::close() !!}
@endsection
Quick start
Simply import the package with composer:
composer require bgaze/laravel-blade-indenter
Configuration can be published to /config/blade-indenter.php:
php artisan vendor:publish --tag=blade-indenter-config
The package exposes a single service which indents a Blade string :
$indentedString = resolve(\Bgaze\BladeIndenter\BladeIndenter::class)->indent($stringToIndent);
Two helpers are also provided for convenience :
// Indent a string
$indentedString = indent_blade_string($stringToIndent);
// Indent a blade file, overwrite it and return formatted content.
$indentedFileContent = indent_blade_file($filePath);
// Indent a blade file and return formatted content without overwriting.
$indentedFileContent = indent_blade_file($filePath, false);
Configuration
The indenter supports Blade directives described in official
documentation.
However, if needed, you can customize supported tags and directives
(check package configuration for defaults).
Two ways to do that:
- publish and edit package configuration.
- configure BladeIndenter from the boot section of a Service provider.
As an example, here is the way to configure the indenter for bgaze/bootstrap-form custom directives.
// From boot method of App\Providers\AppServiceProvider:
resolve(\Bgaze\BladeIndenter\BladeIndenter::class)
// @close directive closes @open, @vertical, @horizontal and @inline directives
->addClosingDirectives([
'open' => 'close',
'vertical' => 'close',
'horizontal' => 'close',
'inline' => 'close',
])
// Indent level won't change on line after one of these directives
->addSelfClosingDirectives([
'text', 'email', 'url', 'tel', 'number', 'date', 'time', 'textarea',
'password', 'file', 'hidden', 'select', 'range', 'checkbox', 'checkboxes',
'radio', 'radios', 'label', 'submit', 'reset', 'button', 'link',
]);
Self-closing HTML tags
Indentation level won't increase after these HTML tags.
Edit self_closing_tags section in configuration or use following methods:
/**
* @param array $tags
* @return BladeIndenter
*/
public function setSelfClosingTags(array $tags);
/**
* @param array $tags
* @return BladeIndenter
*/
public function addSelfClosingTags(array $tags);
Self-closing Blade directives
Indentation level won't increase after these directives.
Edit self_closing_directives section in configuration or use following methods:
/**
* @param array $directives
* @return BladeIndenter
*/
public function setSelfClosingDirectives(array $directives);
/**
* @param array $directives
* @return BladeIndenter
*/
public function addSelfClosingDirectives(array $directives);
Closing Blade directives
The "end" version of any directive is supported (for instance @endsection for
@section),
but some directives can also be closed by other directives, like @show closes
@section.
Edit closing_directives section in configuration or use following methods to define
the mapping of these behaviours (without @ character).
/**
* @param array $directives
* @return BladeIndenter
*/
public function setClosingDirectives(array $directives);
/**
* @param array $directives
* @return BladeIndenter
*/
public function addClosingDirectives(array $directives);
Examples:
'closing_directives' => [
'section' => 'show',
'opening_directive_2' => ['closing_directive_21', 'closing_directive_22'],
],
Else Blade directives
Else directive will be indented one level down, but previous level will be preserved on following line.
Edit else_directives section in configuration or use following methods:
/**
* @param array $directives
* @return BladeIndenter
*/
public function setElseDirectives(array $directives);
/**
* @param array $directives
* @return BladeIndenter
*/
public function addElseDirectives(array $directives);
Other packages
Feel free to visit my other packages:
bgaze/bootstrap-form
Bootstrap 4 & 5 forms builder for Laravel 12+
This package simplifies Bootstrap 4 & 5 forms creation in Laravel applications 12+
It renders Bootstrap 5 markup by default and fully supports Bootstrap 4 for backward compatibility.
Model form binding and automatic error display are supported, as well as most Bootstrap form features: form layouts, custom fields, input groups, and more.
bgaze/laravel-kvstore
Key-value store for Laravel 12 & 13
A database-backed key-value store for Laravel 12 & 13, sized for settings: read on most requests, written rarely.
The whole store is cached as one single entry, so a cold read costs one query for every key at once.
Each entry carries its own cast, so a value always reads back as what it was written as.
SnapStack
100% local browser captures for your AI assistant
SnapStack is a browser extension that captures any tab in one click and stacks it locally, so your AI assistant can read the screenshots on demand over MCP.
Nothing is ever uploaded: captures go only to a small server on your own machine. No account, no telemetry.
Works with any MCP-capable client (Claude Code and others), on Chrome, Edge and Firefox.
@bgaze/color-palette
A grid colour picker in the spirit of Google Docs
Vanilla TypeScript, with a single runtime dependency for the positioning.
It works standalone, ships optional Bootstrap 4 and Bootstrap 5 themes, and is accessible on purpose.