Sharing data between views in Laravel
There are two approaches to sharing data across views in Laravel, view share and view composer. In this tuts I will give you a brief overview of both of them and more importantly what you should be careful about when using composer. Now, let's dive in.
View Share
View share runs before the view object is created and is a key/value storage, just like Session::put(), you put your data under a specific key and you will get a same named variable across your views, a straight forward approach, nothing more needs to be said about it.
<?php
view()->share('key', $value)
Now how would you use it in your application? Well, a common approach is to create a MasterController which all of your controllers will extend instead of the Laravel's Controller class. Or you can extract the logic you need to get your data in a Trait if you prefer that approach over inheritance.
<?php
namespace App\Http\Controllers;
class MasterController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->share('some_key', $this->getData());
}
protected function getData()
{
//Your awesome logic e.g.
return DB::tables('some_table')->get();
}
protected function share($key, $data)
{
view($key, $data);
}
}
View Composer
View composer on the other hand runs after the view object has been created and allows us for more flexibility, you register a callback, either an anonymous function or a class to be executed across multiple views, but there is a catch to this and you need to be careful about it, you need to know that callable will be executed for every view, that means all the sections of content you yield or all those partials you include will also trigger this callback.
<?php
/* Share data across all views */
view()->composer('*', function($view) {
//your awesome logic
$view->with($data);
});
/* Share data across multiple views */
view()->composer(['home.index', 'dashboard.*', 'blog.post'], function($view) {
//do something awesome here as well
$view->with($data);
});
/* Share data using a custom class */
view->composer('*', AwesomeViewComposer::class);
So how do we circumvent this duplicating queries issue? It's really simple, all we need is to create our ViewComposer::class.
<?php
use Illuminate\Contracts\View\View;
class ViewComposer {
protected $data;
/**
* Create a new ViewComposer instance.
*/
public function __construct()
{
$this->data = 'Your data';
}
/**
* Compose the view.
*
* @return void
*/
public function compose(View $view)
{
$view->with('shared_data', $this->data);
}
}
And register it as a singleton, in either the AppServiceProvider or our custom ViewComposerServiceProvider.
<?php
namespace App\Providers;
use App\Channel;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\View\Factory;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(Factory $view)
{
$view->composer('*', ViewComposer::class);
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->singleton(ViewComposer::class);
}
}
That's it, have fun building your next project!