Extending Laravel's Blade Posted on January 19th, 2016

Lets assume you want to convert DateTime objects into human readable strings easily in your blade files. The laravel docs suggests adding the following code snippet into AppServiceProvider::boot method:

// allows @datetime(new \DateTime('now')) to display the current date and time Blade::directive('datetime', function($expression) { return "<?php echo with{$expression}->format('m/d/Y H:i'); ?>"; });

This is pretty simple. However it's a little more complex to abstract the format into a second parameter for the datetime directive e.g.: @datetime(new \DateTime('now'), 'm/d/Y H:i') . Rather than using regex to get the 2 separate parameters, I like to create a self executing class capable of handling any number of parameters.

class DateFormatter { public function __invoke(\DateTime $date, $format) { return $date->format($format); } }

Remember, when you add the __invoke method to any class, it can be executed like a closure.

$formatter = new \DateFormatter(); echo $formatter(new \DateTime('2016-01-19'), 'Y'); // 2016

The Blade::directive should now be updated to use our DateFormatter class and a DateFormatter instance should be injected into the templates.

// Inject DateFormatter instance into all templates View::with('dateFormatter', new \DateFormatter); // Update directive to use `DateFormatter` Blade::directive('datetime', function ($expression) { return "<?php echo \$dateFormatter{$expression}; ?>"; });

Imagine the following template code:

Registered on @datetime($user->createdAt, 'Y-m-d')

When the template is compiled, the above line will be compiled to: