Laravel 5 - global Blade view variable available in all templates

87,149

Solution 1

Option 1:

You can use view::share() like so:

<?php namespace App\Http\Controllers;

use View;

//You can create a BaseController:

class BaseController extends Controller {

    public $variable1 = "I am Data";

    public function __construct() {

       $variable2 = "I am Data 2";


       View::share ( 'variable1', $this->variable1 );
       View::share ( 'variable2', $variable2 );
       View::share ( 'variable3', 'I am Data 3' );
       View::share ( 'variable4', ['name'=>'Franky','address'=>'Mars'] );
    }  

}

class HomeController extends BaseController {

    //if you have a constructor in other controllers you need call constructor of parent controller (i.e. BaseController) like so:

    public function __construct(){
       parent::__construct();
    }

    public function Index(){
      //All variable will be available in views
      return view('home');
    }

}

Option 2: Use a composer:

  1. Create a composer file at app\Composers\HomeComposer.php

NB: create app\Composers if it does not exists

<?php namespace App\Composers;

class HomeComposer
{

    public function compose($view)
    {
        //Add your variables
        $view->with('variable1',      'I am Data')
             ->with('variable2',      'I am Data 2');
    }
}

Then you can attached the composer to any view by doing this

<?php namespace App\Http\Controllers;

use View;

class HomeController extends Controller{


    public function __construct(){

        View::composers([
            'App\Composers\HomeComposer'  => ['home'] //attaches HomeComposer to home.blade.php
        ]);

    }

    public function Index(){
        return view('home');
    }

}

Option 3: Add Composer to a Service Provider, In Laravel 5 I prefer having my composer in App\Providers\ViewServiceProvider

  1. Create a composer file at app\Composers\HomeComposer.php

  2. Add HomeComposer to App\Providers\ViewServiceProvider

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use View;
use App\Composers\HomeComposer;
use Illuminate\Support\Facades\Blade;

class ViewServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
 *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //add to all views
        view()->composer('*', HomeComposer::class);
        //add to only home view 
        //view()->composer('home', HomeComposer::class);
    }
}

Solution 2

Create a new Service Provider as suggested in here

Add your new Service Provider to the configuration file (config/app.php).

In the boot method of your new Service Provider use:

View::share( 'something_cool', 'this is a cool shared variable' );

Now you are ready to use $something_cool in all of your views.

Hope this helps.

Solution 3

Searching for solution of the same problem and found the best solution in Laravel documentation. Just use View::share in AppServiceProvider like this:

View::share('key', 'value');

Details here.

Solution 4

You can do this with view composers. View composers are executed when a template is loaded. You can pass in a Closure with additional functionality for that view. With view composers you can use wildcards. To make a view composer for every view just use a *.

View::composer('*', function($view)
{
    $view->with('variable','Test value');
});

You can also do this without a closure as you can see in the docs.

View::composer('*', 'App\Http\ViewComposers\ProfileComposer');

The profile composer class must have a compose method.

View composers are executed when a view is rendered. Laravel has also view creators. These are executed when a view is instantiated.

You can also choose to use a BaseController with a setupLayout method. Then every view which you will load is loaded through the setupLayout method which adds some additional data. However, by using view composers you're pretty sure that the code is executed. But with the BaseController approach you've more flexibility because you can skip the loading of the extra data.

EDIT: As mentioned by Nic Gutierrez you can also use view share.

Solution 5

Also, you can do this in the Route.php file:

view()->share('variableName', $variable);
Share:
87,149
Limon Monte
Author by

Limon Monte

Has SweetAlert2 helped you create an amazing application? You can show your support by making a donation: https://github.com/sponsors/limonte https://www.paypal.me/limonte

Updated on July 05, 2022

Comments

  • Limon Monte
    Limon Monte almost 2 years

    How can I in Laravel 5 make global variable which will be available in all Blade templates?

  • Chad Priddle
    Chad Priddle over 8 years
    Your response really helped me with Option 1, although what if you're trying to access $user = Auth::user(); and pass the $user variable to all of the blade templates including the header and the content part? I tried this by putting the $user variable in the BaseController and then sharing it, but if I var_dump $user I get a bunch of protected values in the array. Basically I want to be able to access all of the auth user variables throughout the app in all templates and views. Seems simple but have spent hours trying to figure it out.
  • Chad Priddle
    Chad Priddle over 8 years
    Actually this worked: <?= $user['name']; ?> but this didn't work: {{ $user->name }}
  • Emeka Mbah
    Emeka Mbah over 8 years
    @Chad Priddle This should work for an array {{ $user['name'] }} while this works for an object {{ $user->name }}
  • Petecoop
    Petecoop about 8 years
    The difference between this and view()->share is that this is only run when a view is used - but with view()->share it's ran no matter what - you might be returning some JSON in an API call for example - which doesn't use a view.
  • luchaos
    luchaos about 8 years
    plus, it's the ultimate solution for variables used on multiple occasionson a 503 page after artisan down. Injecting an app's version string as cache buster parameter or having it displayed in the footer whilst updating is a chore with other solutions. (using an env variable for that would probably be the cleanest solution though)
  • Christophvh
    Christophvh over 7 years
    this is a better solution than the approved answer
  • Nicolas
    Nicolas over 7 years
    I think the main difference is that the user is asking on how to have a global variable available in all templates. With the accepted solution the user needs to remember to extend BaseController and call parent::construct and with the ViewComposer solution he needs to call View::composers in every controller construct method in order to make the variables available.
  • lewis4u
    lewis4u over 7 years
    This should be chosen as an answer!
  • Kokodoko
    Kokodoko about 5 years
    For option 1 I get: Class 'App\Http\Controllers\View' not found
  • jave.web
    jave.web over 4 years
    Did not work for Auth::user() - in that state it was null - however the place is correct, I just needed to add it through composer View::composer('*', function($view) { $view->with('current_user', Auth::user()); } instead of the share.
  • Neekobus
    Neekobus about 4 years
    The recommended way should be : a service provider with View::share. Note that the composer "*" option is called for every template loaded : if you do a DB call, it will be done for every views and subviews !
  • Ariful Islam
    Ariful Islam over 2 years
    This is best I answer and easy to use.