Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override section in a laravel blade template throwing undefined variable errors

I am using Laravel 4 and blade templates, and running into an issue when I try and extend a template.

In my layout I have

@yield('content')

and in my page I have

@section('content')
    Welcome {{ $name }}
@stop

which works fine, I've created another page very similar to my first, and just want to change override the admin content section. The other sections in the template are fine.

so I extend my page, and do

@section('content')
    Hello!
@stop

I get an undefined notice with the $name variable.

I tried

@section('content')
    Hello!
@overwrite

and same deal, I get the notice error. I checked my controller and it IS using the correct template. I am not calling @parent so I don't understand, how can I overwrite a section in a template with out notice errors?

like image 871
Wizzard Avatar asked Oct 15 '13 10:10

Wizzard


1 Answers

Blade layouts work their way up the tree to the route or master view before rendering any of the children. Thus, nested views that extend others must always have their parent rendered before they are. As a result, parent views that contain sections will always be rendered prior to the child.

To overcome the problem you are experiencing it is a good idea to only ever nest pages that don't overwrite parents sections that contain variables, as the parents content will always be rendered before the child.

As the above ideal can't always be adhered to or a parents section content is still required, a good alternative method would be to use view composers. View composers give you an opportunity to declare variables for any specific view whenever they are rendered.

View::composer(array('pages.admin'), function($view)
{
    $view->with('name', Auth::user()->username);
});

Another alternative would be to use a view creator. Creators are fired the moment a view is instantiated rather than rendered. This method allows you to overwrite the variable should you so wish prior to the view being rendered.

View::creator(array('pages.admin'), function($view)
{
    $view->with('name', Auth::user()->username);
});

You can read up more about these methods in the documentation here. (Or here for the Laravel 5 documentation.)

like image 88
David Barker Avatar answered Sep 28 '22 02:09

David Barker