Jobinja / blade-macro by jobinja

Reusable scope-protected blade blocks, with empty I/O on runtime (replacement for @include which uses native I/O based PHP includes).
4,802
7
5
Package Data
Maintainer Username: jobinja
Maintainer Contact: pcfeeler@gmail.com (Reza Shadman)
Package Create Date: 2016-12-24
Package Last Update: 2018-06-08
Home Page:
Language: PHP
License: MIT
Last Refreshed: 2024-12-11 15:00:49
Package Statistics
Total Downloads: 4,802
Monthly Downloads: 66
Daily Downloads: 0
Total Stars: 7
Total Watchers: 5
Total Forks: 4
Total Open Issues: 1

Blade Macro

This package introduces a new blade directive called @macro which allows reusable scope-protected blade code blocks. Just like what @include does but with zero runtime I/O.

@include uses native PHP include directive, which causes runtime I/O, Event if Opcache is fully enabled. But sometimes @include is used when we want to just Don't repeat ourselves But this abstraction should not cause any performance bottleneck.

Installation

For Laravel >= 5.5.0:

composer require jobinja/blade-macro

For Laravel <= 5.3.0:

composer require jobinja/blade-macro:1.0.*

Usage

Just use the following service provider in your app.php:

[
    \JobinjaTeam\BladeMacro\JobinjaBladeMacroServiceProvider::class,
    //...
]

Then you can simply replace your needed old @include directives with the new @macro one:

@include('some_partial', ['some_var' => 'some_value')

// Should be replaced with:
@macro('some_partial', ['some_var' => 'some_value'])

Configuration

By default the package re-compiles blade views on each request in development environment, if you want to disable this feature run:

php artisan vendor:publish --provider=JobinjaTeam\BladeMacro\JobinjaBladeMacroServiceProvider

and config the package based on your needs.

Problem

Please see #16583 or simply read the following:

Consider the following loop:

@for($i=1; $i < 500000; $i++)
    @include('iteration_presenter', ['iteration' => $i])
@endfor

The above code will be replaced by something like the following:

<?php for($i=1; $i < 5000000; $i++){ ?>
    <?php
        // Just for example in real world laravel wraps this
        // around a method to satisfy scope protected data.
        include './blade_compiled_path/iteration_presenter.php';
    ?>
<?php } ?>

The above code includes the iteration_presenter.blade.php file for 5,000,000 times, which causes heavy I/O calls, but the only reason we have used the iteration_presenter partial is to create more abstraction and don't repeat ourselves.

Solution

Instead of using native include directive we have created a new @macro directive which simply copy/pastes the partial content in compile time, and simply there is no I/O then:

@for($i=1; $i < 500000; $i++)
    @macro('iteration_presenter', ['iteration' => $i])
@endfor

The above @macro directive will be translated to the following:

<?php for($i=1; $i < 5000000; $i++){ ?>
    <?php (function ($scopeData) { extract($scopeData); ?>

    <?php echo e($iteration);?>

    <?php })($someHowComputedScope) ;?>
<?php } ?>

Running tests

composer test

License

Licensed under MIT, part of the effort for making Jobinja.ir better.