Limon Monte
Limon Monte

Reputation: 54449

Laravel 5 - global Blade view variable available in all templates

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

Upvotes: 71

Views: 97287

Answers (9)

Emeka Mbah
Emeka Mbah

Reputation: 17553

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 attach 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);
    }
}

Upvotes: 106

Gabi Dj
Gabi Dj

Reputation: 627

I would rather use middleware with the view() facade helper. (Laravel 5.x)

Middleware is easier to mantain and does not make a mess in the controllers class tree.

Steps

Create the Middleware

/app/Http/Middleware/TimezoneReset.php

To create a middleware you can run php artisan make:middleware GlobalTimeConfig

share() the data you need shared

 <?php

    namespace App\Http\Middleware;

    use Closure;

    class GlobalTimeConfig
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            $time_settings = [
                'company_timezone' => 'UTC',
                'company_date_format' => 'Y-m-d H:i:s',
                'display_time' => true,
            ];

            view()->share('time_settings', $time_settings);

            return $next($request);
        }
    }

Register the newly created middleware

Add the middleware to your middleware route group as per example below

/app/Http/Kernel.php

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\GlobalTimeConfig::class,
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

Access data from templates

Access the data from any template with the given key in the View::share() method call

eg.:

    Company timezone: {{ $time_settings['company_timezone'] }}

EDIT: Nic Gutierrez's Service Provider answer might be a better (or the best) solution.

Upvotes: 2

Ehab Elzeny
Ehab Elzeny

Reputation: 244

and you can give array not just View::share('key', 'value'); can put array like View::share(['key'=>'value','key'=>'value'])

Upvotes: 1

Arshad Jilani
Arshad Jilani

Reputation: 121

You can add in Controller.php file:

use App\Category;

And then:

class Controller extends BaseController {
     public function __construct() {
        $categories = Category::All();
        \View::share('categories', $categories);
     }
}

Upvotes: -2

Nicolas
Nicolas

Reputation: 894

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.

Upvotes: 41

Jodeveloper8
Jodeveloper8

Reputation: 104

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

view()->share('variableName', $variable);

Upvotes: 4

sha-1
sha-1

Reputation: 2093

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.

Upvotes: 18

Jeff
Jeff

Reputation: 166

you can flash it into the session, you can define it in the .env file (static vars)

Upvotes: -7

ArjanSchouten
ArjanSchouten

Reputation: 1368

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.

Upvotes: 11

Related Questions