Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Same section name in blade inherited templates

Let's say i have three blade templates: A, B and C. Template A is the global layout, template B is some specific section's layout and template C is the view template.

Templates A and B expect a section called content to be assigned. That section is defined in the view templates (C).

Here's a simplified version of templates A and B:

Template A:

<html>
  <body>
    @yield('content')
  </body>
</html>

Template B:

@extends('template_a')

@section('content')
<div class="sidebar">
  ...
</div>
<div class="content">
  @yield('content')
</div>
@endsection('content')

As you can see, both templates output a content section. My problem is that in views that extend B it's content is simply ignored. The content section defined in the view is output on the @yield('content') present at template A.

I would like to know if it is possible to propagate the content section up in the view hierarchy, i.e., replacing the the content placeholder in template B with the value defined in template C and replace the result in content placeholder in template A.

Sorry if i made this sound too confusing. I hope you get my idea.

Thanks in advance.

like image 359
Gonçalo Marrafa Avatar asked Mar 17 '16 23:03

Gonçalo Marrafa


2 Answers

I found an answer to your problem here: https://laracasts.com/discuss/channels/laravel/trouble-with-blade-section-inheritance?page=1

The trick is to use @overwrite instead of @endsection in the blades that contain a @yield inside a @section with the same name.

@extends('app')
@section('content')
    {{--Some common code--}}
    @yield('content')
@overwrite

Using @endsection causes yielded views to override the intermediate view, but using @overwrite forces inclusion along the way.

The confusing thing, in my opinion, is that in conventional programming the directive to make use of the superclass method goes in the subclass (calling the superclass method from the subclass) whereas in Laravel blade inheritance it must be placed in the superclass itself (the superclass declares within itself that it cannot be ignored when overridden).

like image 134
Ron Avatar answered Dec 19 '22 12:12

Ron


Just rename the @yield('content') in Template B. A @endsection (Laravel5) is enough to end those sections.

Template A:

<html>
  <body>
    @yield('body')
  </body>
</html>

Template B:

@section('body')
   <div class="sidebar">
      ...
   </div>
   <div class="content">
      @yield('content')
   </div>
@endsection

Template C:

@section('content')
    <!--yourContent-->
@endsection

This way you can easily change your Template B with any other given Template to modify the body (i.e. Template D):

@section('body')
   <!-- Some different Body Style -->
      @yield('content')
@endsection

as well as your content (i.e. Template E):

@section('content')
    <!--some different Content-->
@endsection

Edit:

Probably the reason for Template B not showing any data from Template C is an infinite Loop caused by Template B: Every time you call the section('content') you also yield('content') and inserting Template B into itself.

like image 34
Tim L Avatar answered Dec 19 '22 10:12

Tim L