Creating Custom Laravel Blade Directive
Sometimes we need custom controls or custom directives to control the appearance of our views.
By the time your application getting scaled, you need something reusable instead of copy pasting the code again and again. You often need to write complex login and conditions in your views which makes your views messy and are less maintainable.
You can clean up your blade views with Custom Laravel Blade Directives. In this post, we will look at how we can create reusable custom directives and use them.
Laravel Blade Directives
Laravel Blade template engine compiles it’s special syntax back to PHP and HTML code. Its special syntax includes directives, which are just a pretty interface hiding ugly logic code behind. Laravel Blade’s directives are very handy and powerful for a simple application but your code starts smelling as your application grow and you will have a feel to refactor the parts of your view’s logic to custom blade directives.
You might be already familiar with existing blade directives such as @section, @yield, @foreach and list goes on.
Let’s start with creating a simple directive.
Defining a Custom Blade Directive
You can define a custom blade template using Blade:: facade inside a service providers’s boot()
method something like below.
Blade::directive('directive_name', function ($expression) { return $expression; });
Let’s define a new blade directive called @hello by declaring in AppServiceProvider like below.
namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\Blade; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { Blade::directive('hello', function ($expression) { return "<?php echo 'Hello '.{$expression}; ?>"; }); } }
Then in your view you can use it like below:
@hello('LaraShout')
Blade Directive Practicle Example
Above example is super easy for learning, now let’s create some useful directive for practical use.
Creating Service Provider
As we defined our custom blade directive in AppServiceProvider which is OK, but I will recommend to create a new service provider for your all custom blade directives and try to avoid anything in the AppServiceProvider.
Createa custom service provider called BladeServiceProvider with below command.
php artisan make:provider BladeServiceProvider
Above this command will create a service provider in app/Providers
folder with below code.
namespace App\Providers; use Illuminate\Support\ServiceProvider; class BladeServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // } /** * Bootstrap services. * * @return void */ public function boot() { // } }
Now before adding custom blade directives let’s register this service provider in Laravel by adding it to $providers
array in config/app.php
file.
Add below to the $providers
array.
App\Providers\BladeServiceProvider::class,
Now our new service provider is registered in Laravel service container we can start adding custom blade logic.
Adding Custom Directive
I want to create a custom blade directive which will check if the current route is equal to the one we will provide.
Add below code in BladeServiceProvider‘s boot()
method.
Blade::directive('routeis', function ($expression) { return "<?php if (fnmatch({$expression}, Route::currentRouteName())) : ?>"; }); Blade::directive('endrouteis', function ($expression) { return '<?php endif; ?>'; });
In above code example, we are defining two custom blade directives called routeis and endrouteis. In the first directive we are executing a if statement to check if the $expression
is matching the current route using Route facade’s method currentRouteName()
by applying PHP’s native function fnmatch()
.
In the second blade directive, we are simply, closing the if statement.
Now we can use the above blade directive like below.
@routeis('home') // Your stuff here @endrouteis
If the current route will be named home
, then it will render whatever will be within this directive.
Similary way we can define a new custom facade to do the opposite of above one. Now we will declare two new custom blade directives called routeisnot and endrouteisnot. Add below code to the same boot()
method of BladeServiceProvider.
Blade::directive('routeisnot', function ($expression) { return "<?php if (! fnmatch({$expression}, Route::currentRouteName())) : ?>"; }); Blade::directive('endrouteisnot', function ($expression) { return '<?php endif; ?>'; });
In the above blade directive, it’s just checking if the current route is not the one as $expression
.
You can use the above blade directive like below:
@routeisnot('home') // Your stuff here @endrouteisnot
Conclusion
This is more than enough on Laravel Blade Custom Directives and how we can clean up our views by extracting simple logic to custom blade directives.
If you have any question or suggestion to improve this post, please leave them in the comments box below.