Laravel: How to define custom Blade directives

Updated: January 15, 2024 By: Guest Contributor Post a comment

Introduction

Laravel’s Blade templating engine provides a very powerful and flexible way to manage the presentation logic in your application. In addition to the built-in directives such as @if, @foreach, and @include, Blade also allows us to define custom directives to add even more functionality to our views. In this tutorial, we’ll explore how to create these custom directives in Laravel, starting with basic examples and then moving to more advanced uses.

Basic Custom Blade Directive

Custom Blade directives are useful for registering PHP code that you want to use as part of your Blade templates. Each directive is defined with a specific keyword, and the directive is defined using the directive method provided by the Blade templating engine.

Here’s how you can define a simple custom directive:

Blade::directive('uppercase', function ($expression) {
    return "";
});

Once the directive is defined, you can use it in your Blade templates like so:

@uppercase('hello world')

This custom directive will take the string passed to it and convert it to uppercase. The output would be:

HELLO WORLD

Parameterized Directives

Often, we need to pass parameters to our directives. Let’s define a directive that formats a given date:

Blade::directive('formatDate', function ($expression) {
    return "";
});

To use this directive, you would pass a Carbon instance to the directive:

@formatDate(now())

Your dynamic output format would look like this:

01/23/2023

(Assuming the current date is January 23rd, 2023)

Advanced Usage

Let’s make a directive that is more complex. For instance, we may want to create a directive that checks for permissions:

Blade::directive('permission', function ($expression) {
    if(auth()->user()->hasPermission($expression)) {
        return "";
    } else {
        return "";
    }
});

This directive can be utilized to protect certain parts of your website at the Blade level:

@permission('edit_post')
<button>Edit Post</button>
@endpermission

An unauthorized access would result in an HTTP 403 error.

Using Service Providers to Organize Directives

If your application uses multiple custom Blade directives, it makes sense to organize them within a service provider. You can create your own BladeServiceProvider and define your custom directives all in one place:

php artisan make:provider BladeServiceProvider

Then, add your directives in the boot method:

public function boot()
{
    Blade::directive('upper', function ($expression) {
        return "";
    });

    // Other directives...
}

Don’t forget to register your service provider in the config/app.php‘s providers array.

Caching Issues and the if Directive Method

It’s worth noting that due to Blade’s caching mechanism, the code within your directive is only evaluated when the view is compiled. This can lead to problems when the result of your directive is supposed to change with each request. A solution to this problem is to use the if directive method to register conditionals that are evaluated on each request:

Blade::if('env', function ($environment) {
    return app()->environment($environment);
});

Then in your blade file:

@env('local')
    // The application is in the local environment
@endenv

Conclusion

In conclusion, custom Blade directives are a very effective tool to keep your Blade files clean and maintainable. As we have seen, starting with the basics, through to more advanced technologies, Laravel’s blade templating engine provides immense flexibility to developers, making it extremely effective for crafting a responsive and interactive user interface.