jobinja/blade-macro

Reusable scope-protected blade blocks, with empty I/O on runtime (replacement for @include which uses native I/O based PHP includes).

2.0.0 2018-06-08 07:39 UTC

This package is not auto-updated.

Last update: 2024-12-16 11:03:39 UTC


README

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.