Today I was trying to figure out this difference as well, and where to use each, and why would I want to use one over the other. Please be warned this answer is verbose and probably very over-explained.
Snapey from the Laracasts forums got me started thinking about them properly:
https://laracasts.com/discuss/channels/laravel/whats-the-difference-between-atinclude-and-atyield
First off, @include is going to include an entire file, just like the PHP include function. That's great if you're just dumping an entire file of content into the <body>
of your page, for example the following is going to include everything inside of 'content.blade.php':
<!-- layout.blade.php -->
<body>
@include('content')
</body>
<!-- content.blade.php -->
<div>
<div>
<p>Hey this is my content.</p>
</div>
<div>
<span>and stuff</span>
</div>
</div>
But @yield, in conjunction with @extends and the @section and @endsection directives, will allow you to have your content chunked into separate sections, but kept all in one file. Then you can @yield it into the layout in separate chunks. The visual that comes to mind is shuffling one half of a deck of cards into the other half, in a classic "riffle" shuffle:
<!-- content.blade.php -->
@extends('layout')
@section('top_content')
<h1>Hey I'm the title</h1>
@endsection
@section('middle_content')
<p>Hey how's it going</p>
@endsection
@section('other_content')
<p>It's over now.</p>
@endsection
<!-- layout.blade.php -->
<body>
<div>
@yield('top_content')
</div>
<p>Some static content</p>
<div>
@yield('middle_content')
</div>
<p>Some more static content</p>
<div>
@yield('other_content')
</div>
<div>Static footer content of some kind</div>
</body>
Secondly and maybe more importantly, the flow of control is sort of inverted, in a way that makes everything much more coherent. In the first example, with @include, you'd be calling the layout file with the view helper, in sort of a top-down way. For example this might be your code:
Route::get('/', function () {
return view('layout');
});
But with @yield and @extends, (as in the second example) you call the content file itself, and the content file will first look at the @extends directive to drape itself with the layout file, like it is putting on a coat. So it happens in reverse, in a sense, like bottom-up. Then the @yield directives inject the content as specified. The content file is who you are talking to in your router/controller:
Route::get('/', function () {
return view('content');
});
You call the content view, it looks at the @extends directive to pick the layout, and then the @yield directives in the layout file inject the matching @section sections into the layout.
So this way is much more useful because in practice you'll be referring to different content when you refer to different views.
If you were only using the @include statement to build your views, then you'd have to pass a different content slug to the layout file that you are calling every time, maybe like this:
Route::get('/welcome', function () {
return view('layout', ['content' => 'welcome']);
});
Route::get('/profile', function () {
return view('layout', ['content' => 'profile']);
});
<!-- layout.blade.php -->
<body>
@include($content)
</body>
And that seems like a mess to me.
That all being said, @include seems like a great way to include a little snippet in your layout file (the one called by the @extends directive), like the nav bar, or the footer, or something you just want to separate out of your layout file for organizational purposes.
@yield
and@include
injects HTML into a parent file. Laravel documentation is also very poor. It is not targeted at person who is new to laravel. The main difference between@yield
and@include
is:@include
defines view to inject into parent.@yield
defines section to be injected.@yield
works only if your view@extends
the parent view. – Flip