I am using Blade to include multiple sub-views into a single set of tabs in a blade app. All of the sub-views have the same overall structure (a sidebar and a main section). Because of this, I have created a template and each sub-view extends the template. Here is the structure:
Main.blade.php
<div id="tabs">
<ul>
@foreach($views as $view)
<li><a href="#{{$view}}">{{$view}}</a></li>
@endforeach
</ul>
@foreach($views as $view)
<div id="{{$view}}">
@include($view)
</div>
@endforeach
</div>
template.blade.php
{{-- formatting stuff --}}
@yield('content 1')
{{-- more formatting stuff --}}
@yield('content-2')
{{-- more formatting stuff --}}
tab-*.blade.php
@extends('template')
@section('content-1')
This is tab [whatever number]
@stop
@section('content-2')
Lorem Ipsum
@stop
The obvious problem here is that, as each sub-view extends the same template, the @yield('content')
exists 3 times, and all 3 included sub-views have their own @section('content')
. What appears to be happening is that the first sub-view's implementation of the content section is getting placed in all 3 yields.
My intent here is obvious. I want each included sub-view to implement it's own instance of the template, place it's content in the content section, THEN get pulled into the main page. Can this be done?
If I flatten the tab-*.blade.php files and stop using the template, it works fine. The problem here is that I end up with a lot of code repetition that would be better placed in a template. This is an emergency option, but I'd like to do it the "proper" way.
NOTE
I have tried to redesign this to avoid the problem, but I really can't come up with another solution. While @include
is typically used to pull in small, static pieces (a header, a footer, etc.), I have not read anything that states this as a restriction. It seems to me that the best approach is to store each view once and pull them into the main page when needed, so that's how I've designed it.
Try using the @overwrite
command instead of @stop
Example:
@extends('template')
@section('content-1')
Stuff goes here...
@overwrite
@section('content-2')
More stuff goes here...
@overwrite
Source: https://github.com/laravel/framework/issues/1058#issuecomment-17194530
I came up with a hack that seems to work. In template.blade.php, I use the following:
{{-- formatting stuff --}}
@yield(isset($tab) ? "content-1-$tab" : 'content-1')
{{-- more formatting stuff --}}
@yield(isset($tab) ? "content-2-$tab" : 'content-2')
{{-- more formatting stuff --}}
Then, in main.blade.php, I execute @include('view', ['tab'=>$view])
. This seems to cause each instance of content-1
and content-2
do be named distinctly, allowing the 2 subviews to implement the sections separately. This also should allow any other views that implement this template to continue to function without having to change anything.
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