I am using a Laravel view composer to share a couple of variables with all views.
app/composers.php:
View::composer('layouts.base', 'MyApp\Composers\BaseComposer');
My understanding here is that anything that uses layouts.base will get the view composer data.
BaseComposer@compose, simplified:
 public function compose($view) {
      // Some logic left out here that pulls in some data
      $data = array(
        'name' => 'John',
        'status' => 'active'
      );
      $data = (object) $data;
      return $view->with('global', $data);
    }
Given this layouts.base:
  {{ $global->name }}
  @include('layouts.partials.header')
  @yield('content')
$global->name is found and so is this in the included layouts.partials.header:
  {{ $global->status }}
But, a view that extends layouts.base throws an Undefined variable: global error:
home.blade.php
@extends('layouts.base')
@section('content')
  {{ $global->name }}
@stop
Everything works fine if I modify composers.php to reference home:
View::composer(['layouts.base', 'home'], 'MyApp\Composers\BaseComposer');
I'd like to understand why if home extends layouts.base it can't see the view composer variables without this extra step.
The problem here is the order of how things happen. View composers get called before the matching view gets rendered. That means in your case:
home gets renderedlayouts.base gets calledlayouts.base gets renderedThis results in the variable global not being available in the home view.
Here are some solutions that may help
Change your composer match pattern to include all the views that need the variable. Make use of the wildcard * if possible.
You can even match each and every view:
View::composer('*', 'MyApp\Composers\BaseComposer');
If you need your data in (nearly) every view anyways you can use View::share during start of the application.
Put this in app/filters.php, app/start/global.php or a similar file
$data = array(
    'name' => 'John',
    'status' => 'active'
);
$data = (object) $data;
View::share('global', $data);
Why do different views need the same global data? Could you maybe move the part of the view that needs the data into a partial view which you can then include?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With