/ Laravel

How to create custom Blade directives in Laravel 5

Blade, included in Laravel, is a great template engine, simple to learn and powerful, but sometimes we need some directive to improve it, for example to define a variable without its weird way to do it.

Laravel allows us to achieve this through a service provider, so let's create our @var directive.

Step 1 - Create the service provider

Move to /app/Providers folder and create a new file called BladeServiceProvider.php or run the command from terminal php artisan make:provider BladeServiceProvider.

It will look like this:

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class BladeServiceProvider extends ServiceProvider {

	/**
	 * Bootstrap any application services.
	 *
	 * @return string
	 */
	public function boot()
	{
        //
	}

	/**
	 * Register any application services.
	 *
	 * @return void
	 */
	public function register()
	{
		//
	}

}

Step 2 - Define our directive

The first thing it's to include the Blade facade, writing use Blade in the top of our code after the namespace declaration.

Now let's move on the boot() method and create a new directive:

// Add @var for Variable Assignment
// Example: @var('foo', 'bar')
Blade::directive('var', function ($expression) {
    //
});

In our callback function we retrieve the $expression provided by the user.
The first thing to do is to remove the round brackets. I don't know why it doesn't it automatically, but it sucks and we have to write it from scratch.

// Add @var for Variable Assignment
// Example: @var('foo', 'bar')
Blade::directive('var', function ($expression) {
    // Strip Open and Close Parenthesis
    $expression = substr(substr($expression, 0, -1), 1);
});

Now we have to split $expression in two parameters and we'll assign them to the variables $variable and $value thank to the list() function from PHP.

// Add @var for Variable Assignment
// Example: @var('foo', 'bar')
Blade::directive('var', function ($expression) {
    // Strip Open and Close Parenthesis
    $expression = substr(substr($expression, 0, -1), 1);
    
    // Split variable and its value
    list($variable, $value) = explode('\',', $expression, 2);
});

With the third arg of explode() function, we define a maximum of two elements to be retrieved.

Now let's remove single quotes from the variable name and if the variable name it's not starting with a dollar, we are gonna add it.

// Add @var for Variable Assignment
// Example: @var('foo', 'bar')
Blade::directive('var', function ($expression) {
    // Strip Open and Close Parenthesis
    $expression = substr(substr($expression, 0, -1), 1);
    
    // Split variable and its value
    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;
  }
});

Now we trim what will be the content of our variable and assign to it.

// Add @var for Variable Assignment
// Example: @var('foo', 'bar')
Blade::directive('var', function ($expression) {
    // Strip Open and Close Parenthesis
    $expression = substr(substr($expression, 0, -1), 1);
    
    // Split variable and its value
    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}; ?>";
});

Done! Simple, right? The complete code will look like this:

<?php namespace App\Providers;

use Blade;
use Illuminate\Support\ServiceProvider;

class BladeServiceProvider extends ServiceProvider {

	/**
	 * Bootstrap any application services.
	 *
	 * @return string
	 */
	public function boot()
	{
        // Add @var for Variable Assignment
        // Example: @var('foo', 'bar')
        Blade::directive('var', function ($expression) {
            // Strip Open and Close Parenthesis
            $expression = substr(substr($expression, 0, -1), 1);

            // Split variable and its value
            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}; ?>";
        });
	}

	/**
	 * Register any application services.
	 *
	 * @return void
	 */
	public function register()
	{
		//
	}

}

Step 3 - Testing!

First, clear your views cache with the command php artisan view:clear and then create a blade file in your Laravel project with this content:

@var('foo', 'bar')

{{ $foo }}

Guess the output? Yes, it will be bar. Definitely better than the standard way of Blade through {{--*/ $foo = 'bar' /*--}}.

Danilo Polani

Danilo Polani

Software Engineer and dreamer in startups. Go, Python, Laravel, Ionic, AngularJS, VueJS, NodeJS, JavaScript, Elasticsearch, Redis.

Read More