
Laravel blade template provides a way to write clean robust view code by the help of directives by extracting the needed logic code into the higher level of the application.
Laravel provides the blade template engine to write the view code of the application. Also it provides to write custom blade directives. Blade directives in a simple definition is just a method that outputs (echo) php expression.
The benefit from this is to write clean short code and leave all the heavy work to the higher level of the application represented in controllers, middleware and service providers.
To write custom blade directives we will use the Blade::directive() method which accepts the directive name and a callback function that outputs the php expression for this directive. All custom directives must be defined in the AppServiceProvider in the boot() method.
Let’s write a custom directive that outputs the current logged in username:
open app/Providers/AppServiceProvider.php
<?php namespace App\Providers; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { Blade::directive('loggedUser', function () { return "<?php echo \Auth::check() ? \Auth::user()->name: ''; ?>"; }); } /** * Register any application services. * * @return void */ public function register() { // } }
To use that directive in any view like this:
@loggedUser
Sometimes when you run the application for the first time an error occurs that’s because you need to clear view cache by using php artisan view:clear
Let’s see another directive with callback that accepts arguments:
<?php namespace App\Providers; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { Blade::directive('formatdate', function ($expression) { return "<?php echo (new \Datetime($expression))->format('m/d/Y H:i'); ?>"; }); } /** * Register any application services. * * @return void */ public function register() { // } }
Then use it as shown:
@formatdate($post->created_at)
What about creating a custom directive like If statement. Laravel provides another method for that purpose Blade::If(). which accepts the name of the if statement and a callback function that returns the result of this statement. This can be used to shorten long conditionals as the below example:
Consider in an ecommerce website we need to check that the product has a discount and this discount valid within a date range, using a normal if statement we can write something like this:
product.blade.php
@if($product->discount == 1 && $product->discount_start_date <= date('Y-m-d') && $product->discount_end_date >= date('Y-m-d')) // echo $price_after_discount @endif
Now to refactor this using custom directive:
app/Providers/App/AppServiceProvider.php
<?php namespace App\Providers; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { Blade::if('discount', function ($product) { return $product->discount == 1 && $product->discount_start_date <= date('Y-m-d') && $product->discount_end_date >= date('Y-m-d'); }); } /** * Register any application services. * * @return void */ public function register() { // } }
Then use the directive as shown:
product.blade.php
<div class="content"> @discount($product) {{ $price_after_discount }} @else {{ $price_without_discount }} @enddiscount </div>
Don’t forget to run php artisan view:clear in order for laravel to detect the newly created directive.