Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

tylernathanreed's avatar

Useful Blade Directives

What Blade Directives do you find yourself adding? Most of my projects end up having a BladeServiceProvider, and here's some quite useful directives that I add:

@continue Directive for Loops:

// Add @continue for Loops
Blade::directive('continue', function($expression)
{
    return '<?php continue; ?>';
});

@break Directive for Loops:

// Add @break for Loops
Blade::directive('break', function($expression)
{
    return '<?php break; ?>';
});

@ifempty Directive for Loops:

This is handy because sometimes you don't actually need the @forelse directive, and only the @empty part.

// Add @ifempty for Loops
Blade::directive('ifempty', function($expression)
{
    return "<?php if(count$expression == 0): ?>";
});

// Add @endifempty for Loops
Blade::directive('endifempty', function($expression)
{
    return '<?php endif; ?>';
});

@optional Directive for Sections:

I often find myself wanting to have a section, but only use it if it's yielded.

// Add @optional for Complex Yielding
Blade::directive('optional', function($expression)
{
    return "<?php if(trim(\$__env->yieldContent{$expression})): ?>";
});

// Add @endoptional for Complex Yielding
Blade::directive('endoptional', function($expression)
{
    return "<?php endif; ?>";
});

Here's an example of where I use @optional:

@optional('overlay')

    <section id="overlay" class="overlay hide">
        <div class="overlay-wrapper">
            <div id="overlay-content" class="overlay-content">
                @yield('overlay')
            </div>
            <button id="overlay-close" class="overlay-close" onclick="overlay.close()">Close</button>
        </div>
    </section>

    @section('footer-left')

        <li id="overlay-open"><a href="javascript:void(0);" onClick="overlay.open()">Open Overlay</a></li>

    @endsection

    @section('tail')

        <script src="/media/js/partials/overlay.min.js"></script>

    @endsection

@endoptional

So, if the overlay section is used, I make sure to have a container for it, an "Open Overlay" button on the footer of the site to re-open the overlay, and the overlay.min.js file used to automatically display the overlay, and control its visibility.

If the section isn't used, then none of this HTML appears, which is great for decluttering a ton of empty containers within my templates.

The last directive that I have is @set, because I end up being so happy using Blade everywhere, that I just don't want to use <?php $var = (Some Value); ?>. Therefore I made the @set directive:

// Add @set for Variable Assignment
Blade::directive('set', function($expression)
{
    // Strip Open and Close Parenthesis
    if(Str::startsWith($expression, '('))
        $expression = substr($expression, 1, -1);

    // Break the Expression into Pieces
    $segments = explode(',', $expression, 2);

    // Return the Conversion
    return "<?php " . $segments[0] . " = " . $segments[1] . "; ?>";
});

What directives do you guys add?

Side Note: @JeffreyWay is there a way to escape the @ formatting? The Blade Directives are being listed as people, even in the Code Blocks.

Double Side Note: This isn't a conversation that would ever have an answer. Having the ability to say "No answer required", or "I'm not looking for an answer", etc. would be nice.

0 likes
12 replies
fatihict's avatar

Hi,

I personally use snippets instead of creating Blade directives. The continue and break directives are added in the newest Laravel version 5.2.12, so you don' t have to create them yourself anymore. See the /src/Illuminate/View/Compilers/BladeCompiler.php file at Github.

1 like
zachleigh's avatar

My most used ones:

        /*
         * Laravel dd() function.
         *
         * Usage: @dd($variableToDump)
         */
        Blade::directive('dd', function ($expression) {
            return "<?php dd(with{$expression}); ?>";
        });

        /*
         * php explode() function.
         *
         * Usage: @explode($delimiter, $string)
         */
        Blade::directive('explode', function ($argumentString) {
            list($delimiter, $string) = $this->getArguments($argumentString);

            return "<?php echo explode({$delimiter}, {$string}); ?>";
        });

        /*
         * php implode() function.
         *
         * Usage: @implode($delimiter, $array)
         */
        Blade::directive('implode', function ($argumentString) {
            list($delimiter, $array) = $this->getArguments($argumentString);

            return "<?php echo implode({$delimiter}, {$array}); ?>";
        });

        /*
         * php var_dump() function.
         *
         * Usage: @var_dump($variableToDump)
         */
        Blade::directive('varDump', function ($expression) {
            return "<?php var_dump(with{$expression}); ?>";
        });

        /*
         * Set variable.
         *
         * Usage: @set($name, value)
         */
        Blade::directive('set', function ($argumentString) {
            list($name, $value) = $this->getArguments($argumentString);

            return "<?php {$name} = {$value}; ?>";
        });

Many of them call the getArguments() method I have on the service provider:

    /**
     * Get argument array from argument string.
     *
     * @param string $argumentString
     *
     * @return array
     */
    private function getArguments($argumentString)
    {
        return explode(', ', str_replace(['(', ')'], '', $argumentString));
    }
brandonferens's avatar

This is a little late, but I've built out the @set directive a little bit more so that it can accept method's as the value parameter

Blade::directive('set', function($expression) {
    list($variable, $value) = explode(',', $expression, 2);

    // Ensure variable has no spaces or apostrophes
    $variable = trim(str_replace('\'', '', $variable));

    // Make sure that the variable starts with $
    if (! starts_with($variable, '$')) {
        $variable = '$' . $variable;
    }

    $value = trim($value);

    return "<?php {$variable} = {$value}; ?>";
});

Hope this helps someone!

2 likes
sarathkumar's avatar

@truncate directive to truncate Strings

example @truncate('Your String' , 4)

 Blade::directive('truncate', function ($expression) {
           
           list($string, $length) = explode(',', str_replace(['(', ')', ' '], '', $expression));
           
           return "<?php echo e(strlen({$string}) > {$length} ? substr({$string},0,{$length}).'...' : {$string}); ?>";

       });
luddinus's avatar

I don't have it but some directive for font-awesome icons, something like:

// second argument optional
@fa('users', '2x')

// equals to
<i class="fa fa-users fa-2x"></i>
1 like
p3ym4n's avatar

@luddinus I made some thing for font-awesome icons. first of all a helper function

function icon($icon,array $attributes = [])
{
    $class = "fa {$icon}";
    if (isset($attributes['class'])) {
        $attributes['class'] = trim($attributes['class']) . ' ' . $class;
    } else {
        $attributes['class'] = $class;
    }
    
    return Html::tag('i', '', $attributes)->toHtml();
}

and then the directive

Blade::directive('icon', function ($expression) {
    return "<?php echo icon({$expression}); ?>";
});

Update : by the way after thinking a lot about the concept I figured it out that it's better to simply use the html syntax.

1 like
sarathkumar's avatar

Export data to javascript window object from blade

 Blade::directive('js', function ($arguments) {
            list($var, $data) = explode(',', str_replace(['(', ')', ' ', "'"], '', $arguments));
            return  "<?php echo \"<script>window['{$var}']= {$data};</script>\" ?>";
        });

example

@js(users,$users)

we can access these data from window object

window.users
1 like
brandonferens's avatar

I got annoyed with my IDE telling me that the syntax was screwy for setting the csrf token in javascript. So I wrote this little directive to remove all the csrf from the layout.

Blade::directive('csrf', function ($namespace) {
    $namespace = trim(str_replace('\'', '', $namespace)) ?: 'Laravel';
    $csrf      = csrf_token();

    $metaTag   = "<meta name=\"csrf-token\" content=\"{$csrf}\">";
    $scriptTag = "<script>window.{$namespace} = {'csrfToken': '{$csrf}'}</script>";

    return $metaTag . $scriptTag;
});

It allows you to change the namespace if you want something different than window.Laravel

@csrf('Laracasts')

Would set it in

window.Laracasts.csrfToken
enkarito's avatar

This service provider laravelgems/blade-escape extends Blade by adding different escaping strategies/directives - @text, @attr, @css, @js, @param

Example:

<style>
.userPrefix:before { content: "@css($content)"; }
</style>
<div>
    <label class="userPrefix">@text($label)</label>
    <input type="text" name="custom" value="@attr($value)"/>
</div>
<a href="/profile?u=@param($username)">Profile</a>
<button onclick="callMyFunction('@js($username)');">Validate</button>
<script>
    var username = "@js($username)";
</script>

Btw, there is a testing page available - http://laragems.com/package/blade-escape/test

phiterf's avatar

I have those two and some others:

Blade::directive('includeJS', function($js){
    return "<script src='{{asset(\"js/$js\")}}'></script>";
});
Blade::directive('includeCSS', function($css){
    return "<link  href='{{asset(\"css/$css\")}}' rel='stylesheet'>";
});
harunaga's avatar

I offten use these things to debug

    protected static function registerDebugDirectives()
    {
        Blade::directive('dd', function ($expression) {
            if (config('app.debug')) {
                return "<?php dd($expression); ?>";
            }
        });
        Blade::directive('log', function ($expression) {
            if (config('app.debug')) {
                return "<?php \Log::info($expression); ?>";
            }
        });
        Blade::directive('debug', function ($expression) {
            if (!config('app.debug')) {
                return "<?php if(false): ?>";
            }
        });
        Blade::directive('enddebug', function ($expression) {
            if (!config('app.debug')) {
                return '<?php endif; ?>';
            }
        });
        Blade::directive('dump', function($param) {
            if (config('app.debug')) {
                return "<?php echo (new Dumper)->dump($param); ?>";
            }
        });
    }

Here the Dumper class when dump formated variable

class Dumper
{

    public function dump($value, $checkEmpty = false, $option = [])
    {
        if ($checkEmpty && empty($value)) {
            return;
        }
        $dumper = new HtmlDumper;
        $dumper->setStyles([
            'default' => 'background-color:#fff; color:#222; line-height:1.2em; font-weight:normal; font:12px Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:100000; margin:0px; display:table; '
        ]);
        $dumper->setDumpBoundaries(
                '<pre class=sf-dump id=%s data-indent-pad="%s"><span class="sf-dump-note"> </span><samp>', 
                '</samp></pre><script>Sfdump(%s)</script>'
        );
        $style = $option['style'] ?? '';
        return "<div tp-ignore='1' style='display:inline-block;$style'>" . $dumper->dump((new VarCloner)->cloneVar($value), true, ['maxDepth' => 0]) . "</div>";
    }

}

To Dump the validation errors:

@dump($errors->getMessages(), true, ['style' => 'position: fixed;right: 0;bottom: 0;'])

Please or to participate in this conversation.