Exploring Laravel’s Custom Blade Directives

However, this wouldn’t work well in my situation because the design allows titles to be two lines long.

Another solution would be to chop off the title at a given length and add an ellipsis using a php snippet like this:

$truncatedTitle = substr($title,0,20) . '...';

But, what if the title is less than 20 characters to start with? We wouldn’t want the snippet to add the ellipsis in that case.

$truncatedTitle = strlen($title) > 20 ? substr($title,0,20)."..." : $title;

By combining a string length check with a ternary operator, we can truncate and add the ellipsis if necessary. If the title is less than 20 characters, we just return it as normal.

None of this is very complicated if you are familiar with vanilla PHP.

However, adding this much PHP to my Blade templates would have really mucked up my otherwise-clean templates. So I decided to drop this functionality into a custom Blade directive that I could reuse where necessary.

Defining a Custom Blade Directive

Fortunately for us, defining a custom Blade directive is a pretty straightforward process. Open up your AppServiceProvider.php file and look for the boot() method.

The basic format goes as follows:

namespace App\Providers; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot() { Blade::directive('helloWorld', function(){ return ""; }); } }

The first parameter will be the name of your directive, which can then be used in your templates.

According to the code above, adding @helloWorld to your template will result in ‘Hello World’ printed to the screen.

namespace App\Providers; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot() { Blade::directive('hello', function($expression){ return ""; }); } }

By using a closure we can pass data into the directive. Therefore, @hello(‘Jesse’) will result in ‘Hello Jesse’ being displayed in the template.

The Custom @truncate Directive

namespace App\Providers; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot() { Blade::directive('truncate', function($expression){ list($string, $length) = explode(',',str_replace(['(',')',' '], '', $expression)); return " {$length} ? substr({$string},0,{$length}).'...' : {$string}); ?>"; }); } }

Breaking it Down

The data passed through to the closure comes in as a string. So if you send @truncate($list->title, 20), the value of $expression will be ($list->title, 20). Unfortunately we cannot pass arrays or objects, so we need to remove the parenthesis and explode the string into variables on the comma. Once we have the variables, we can check the length, truncate, and add an ellipsis if necessary.

Side note: the e() function is a Laravel helper method that runs htmlentities() over a string. In our case, we don’t want the @truncate method to actually display HTML code, so we are using e().

Now I can use @truncate($card->title, 20) and get a properly formatted title, either with or without an ellipsis, depending on the length. Cool!


Originally published at www.laravelfeed.com.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.