How to pass data to all views in Laravel 5?

This target can achieve through different method,

1. Using BaseController

The way I like to set things up, I make a BaseController class that extends Laravel’s own Controller, and set up various global things there. All other controllers then extend from BaseController rather than Laravel’s Controller.

class BaseController extends Controller
{
  public function __construct()
  {
    //its just a dummy data object.
    $user = User::all();

    // Sharing is caring
    View::share('user', $user);
  }
}

2. Using Filter

If you know for a fact that you want something set up for views on every request throughout the entire application, you can also do it via a filter that runs before the request — this is how I deal with the User object in Laravel.

App::before(function($request)
{
  // Set up global user object for views
  View::share('user', User::all());
});

OR

You can define your own filter

Route::filter('user-filter', function() {
    View::share('user', User::all());
});

and call it through simple filter calling.

Update According to Version 5.*

3. Using Middleware

Using the View::share with middleware

Route::group(['middleware' => 'SomeMiddleware'], function(){
  // routes
});



class SomeMiddleware {
  public function handle($request)
  {
    \View::share('user', auth()->user());
  }
}

4. Using View Composer

View Composer also help to bind specific data to view in different ways. You can directly bind variable to specific view or to all views. For Example you can create your own directory to store your view composer file according to requirement. and these view composer file through Service provide interact with view.

View composer method can use different way, First example can look alike:

You could create an App\Http\ViewComposers directory.

Service Provider

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer("ViewName","App\Http\ViewComposers\TestViewComposer");
    }
}

After that, add this provider to config/app.php under "providers" section.

TestViewComposer

namespace App\Http\ViewComposers;

use Illuminate\Contracts\View\View;

class TestViewComposer {

    public function compose(View $view) {
        $view->with('ViewComposerTestVariable', "Calling with View Composer Provider");
    }
}

ViewName.blade.php

Here you are... {{$ViewComposerTestVariable}}

This method could help for only specific View. But if you want trigger ViewComposer to all views, we have to apply this single change to ServiceProvider.

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer('*',"App\Http\ViewComposers\TestViewComposer");
    }
}

Reference

Laravel Documentation

For Further Clarification Laracast Episode

If still something unclear from my side, let me know.


You can either create your own service provider (ViewServiceProvider name is common) or you can use the existing AppServiceProvider.

In your selected provider, put your code in the boot method.

public function boot() {
    view()->share('data', [1, 2, 3]);
}

This will make a $data variable accessible in all your views.

If you rather want to use the facade instead of the helper, change view()-> to View:: but don't forget to have use View; at the top of your file.


The best way would be sharing the variable using View::share('var', $value);

Problems with composing using "*":

Consider following approach:

<?php
// from AppServiceProvider::boot()
$viewFactory = $this->app->make(Factory::class);

$viewFacrory->compose('*', GlobalComposer::class);

From an example blade view:

  @for($i = 0; $i<1000; $i++)
    @include('some_partial_view_to_display_i', ['toDisplay' => $i])
  @endfor

What happens?

  • The GlobalComposer class is instantiated 1000 times using App::make.
  • The event composing:some_partial_view_to_display_i is handled 1000 times.
  • The compose function inside the GlobalComposer class is called 1000 times.

But the partial view some_partial_view_to_display_i has nothing to do with the variables composed by GlobalComposer but heavily increases render time.

Best approach?

Using View::share along a grouped middleware.

Route::group(['middleware' => 'WebMiddleware'], function(){
  // Web routes
});

Route::group(['prefix' => 'api'], function (){

});

class WebMiddleware {
  public function handle($request)
  {
    \View::share('user', auth()->user());
  }
}

Update

If you are using something that is computed over the middleware pipeline you can simply listen to the proper event or put the view share middleware at the last bottom of the pipeline.


I found this to be the easiest one. Create a new provider and user the '*' wildcard to attach it to all views. Works in 5.3 as well :-)

<?php

namespace App\Providers;

use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;

class ViewServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     * @return void
     */
    public function boot()
    {
        view()->composer('*', function ($view)
        {
            $user = request()->user();

            $view->with('user', $user);
        });
    }

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