Blade Indenter

GitHub license Maintenance GitHub release (latest by date)

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.

Github Documentation

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.

Github Documentation

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.

Github Documentation

@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.

Github Documentation