After 2 years of using Laravel, I’d never been a huge fan of blade. When I first met Taylor Otwell at Genghis grill, I probably insulted him by saying:
“I hate blade” - me to Taylor Otwell
However, with the new job I’ve had to dig into blade and blade has really grown on me. I’ve been working on extending Blade functionality to do other neat things and during all this, an idea came to me to treat blade @blocks
like front matter. This isn’t something you’d normally want to do (and we don’t do it for work projects) but let’s do it anyway. Why? Because we can. I’m going to create a @var
extension that allows me to register variables inside of my blade views instead of a controller.
{% include_file media/laravel-blade-var-extension/snippet1.txt %}
So first we have to register our new @var
pattern by using Blade’s extend method.
Blade::extend(function($view, $compiler)
{
$pattern = "/(?<!\w)(\s*)@var\(\s*'([A-Za-z1-9_]*)',\s*(.*)\)/";
$view = preg_replace($pattern, "<?php \$$2 = resolve($3) ?>", $view);
return $view;
});
What does this do? It basically just replaces those variables with lines like this
<?php $user = resolve('User.paginate') ?>
<?php $userList = resolve('User.lists', ['first_name', 'id']) ?>
So what does this resolve function do? It handles resolving the string class.method
for us using Laravel’s IoC container.
function resolve($name, $args = array())
{
$parts = explode('.', $name);
$obj = App::make($parts[0]);
return call_user_func_array(array($obj, $parts[1]), $args);
}
And there we have it. A simple way to inject variables in your Blade views. I am not using this at the moment so it’s only a proof of concept. One nice thing about this approach is that you can easily see all the registered variables inside of your view and know where they come from. But this approach doesn’t allow you the flexibility to re-use views with different variables - which is a primary reason why we use controllers - separation of concerns!