What is the difference between Laravel #extends and #include - php

I'am new to Laravel I just want to know the difference between #extends and #include
#extends('tempalate')
can I use #include to add template file in my laravel project.
#include('tempalate')

To simply put it:
Using #include('') function you are including or adding an existing file.
Using #extends('') your are sending a portion of your file to the extended file.
Which is usually wrapped inside a #section('') function.

As per Laravel Documentation:
Blade's #include directive allows you to include a Blade view from
within another view. All variables that are available to the parent
view will be made available to the included view:
<div>
#include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
When defining a child view, use the Blade #extends directive to
specify which layout the child view should "inherit". Views which
extend a Blade layout may inject content into the layout's sections
using #section directives. Remember, as seen in the example above, the
contents of these sections will be displayed in the layout using
#yield:
<!-- Stored in resources/views/child.blade.php -->
#extends('layouts.app')
#section('title', 'Page Title')
#section('sidebar')
#parent
<p>This is appended to the master sidebar.</p>
#endsection
#section('content')
<p>This is my body content.</p>
#endsection
Laravel -> Blade Templates -> Including Subviews

Related

Laravel Blade: #stop VS #show VS #endsection VS #append

In Laravel, there are different ways of using sections:
#yield('section1') // Filled in by child view
#section('section2')
// Default content, can be overwritten by child
// Different ways of closing the section
#endsection|stop|show|append
Who can tell me what the exact difference is between all of these?
Accoding to this, #stop and #endsection might be the same. (with one having been deprecated, but not anymore)
#endsection and #stop are the same and indicate the end of a section.
The section is not actually rendered on the page until you do #yield('sectionname')
In contrast, #show is equivalent to
#stop
#yield('sectionname')
i.e. it stops and immediately renders the section at that part of the page.
#append is basically equivalent to:
//FileA.blade.php
#section('sectionname')
... content
#stop
//FileB.blade.php
#extends('fileA')
#section('sectionname')
#parent
... more content after content
#stop
Here's some relevant source code:
protected function compileStop() {
return '<?php $__env->stopSection(); ?>';
}
protected function compileEndsection() {
return '<?php $__env->stopSection(); ?>'; //Same code
}
protected function compileShow() {
return '<?php echo $__env->yieldSection(); ?>';
}
Yield section just stops the current section and yields its contents.
I might be late in the party. But in Laravel 7.x series, there is no mention of "#stop" and "#append".
Q: Difference between #endsection and #show
#endsection directive just tells the blade engine where the section actually ends. And to show that section you need to use the #yield directive. If you don't yield that section blade won't show it after rendering the view.
For example in layout view:
<!-- layout -->
<body>
#section('content')
Some Content
#endsection
</body>
The above code has no meaning, of course we have defined a section. But it won't show up in the view to the client. So we need to yield it, to make it visible on the client. So lets yield it in the same layout.
<!--layout-->
<body>
#section('content')
Some content
#endsection
#yield('content')
</body>
Now the above code has some meaning to the client, because we have defined a section and told the Blade engine to yield it in the same layout.
But Laravel provides a shortcut to that, instead of explicitly yielding that section in the same layout, use the #section - #show directive pairs. Therefore the above code can be written as follows:
<!--layout-->
<body>
#section('content')
Some content
#show
</body>
So #show is just a compacted version of #endsection and #yield directives.
I hope I made everything clear. And one more thing, in laravel 7.x to append the content in the section, #parent directive is used.
Found it in quora
#show has similar functionality like #yield but you can use it for more things. When you declare #yield in your layout view you can set default value as well.
app.blade.php
#yield('title', 'Default Title')
and in your child view you can change the title
user.blade.php
#section('title', 'Custom Title')
However, you can set only string for default value in case of #yield. If you want to use some part of html content as a default part, you should use #show
app.blade.php
#section('some_div')
<h1>Default Heading1</h1>
<p>Default Paragraph
<span>Default Span</span>
</p>
#show
in your child view
#section('some_div')
<h1>Custom Heading1</h1>
<p>Custom Paragraph
<span>Custom Span</span>
</p>
#endsection
also you can use both default content and custom content together. just include #parent
#section('some_div')
#parent
<h1>Custom Heading1</h1>
<p>Custom Paragraph
<span>Custom Span</span>
</p>
#endsection

Laravel Blade Conditional #Yield

I have a blade view which makes use of my template using
#extends('layouts.master')
Within that template I want to show 2 buttons if the section on my child view is true, rather than having to include them in every child view that makes use of the template.
For example, my layout (snippet)
#yield('buttons')
<div>
<button>BUTTON 1</button>
<button>BUTTON 2</button>
</div>
#show
#yield('content)
Here's my child view
#extends('layouts.master')
#section('buttons',false)
#section('content')
<p>Hello world!</p>
#endsection
I know it doesn't work the way I've tried but is something like this possible? I've also tried wrapping the #yield('buttons') in an #if but this isn't possible as #yield can only be used in a function apparently.
Within in my master layout I replace #yield with #section
#section('buttons')
<button>BUTTON 1</button>
<button>BUTTON 2</button>
#endsection
Within my child view I use
#section('buttons','')
This replaces the default, if you wish to keep the default and place your additional content before or after then use #parent before or after your additional content for example in my child view:
#section('buttons')
Additional content to be inserted before the buttons in my master layout.
#parent
#endsection
Outputs:
Additional content to be inserted before the buttons in my master layout. BUTTON 1BUTTON 2
Reference: https://laravel.com/docs/5.5/blade

Different headers in different views (Blade template, Laravel)

I use the Bladetemplate of Laravel. Is there a way to set different header for different views with only one include in master.blade.php?
master.blade.php
#include("elements.header")
#yield('content')
#section("footer")
#show
view.blade.php
#extends("layouts.master")
#section("title")
#stop
#section("content")
#include("elements.error")
#section("footer")
#include("elements.footer")
#stop
If you want to include different header templates for different views, there is no need to include anything from your layout. Instead, include the proper header template into a separate section in your views and then display that section in the master template:
master.blade.php
#yield('header')
#yield('content')
viewA.blade.php
#extends("layouts.master")
#section('header')
#include('headerA')
#stop
#section('content')
view content
#stop
viewB.blade.php
#extends("layouts.master")
#section('header')
#include('headerB')
#stop
#section('content')
view content
#stop
This way, each of your views includes different header templates into the header section that will be later displayed in master layout with #yield('header').
In your main layout
<title>#yield('title','Home')</title>
Then In your views Just call
#section('title','My View 1')
#section('title','My View 2')
The second parameter in yield is the default if none defined.

Laravel - How to load content with new URL

I have inherited a Laravel project to which I need to add a new page with some functionality that I have created. What I've got appears to be a main "app.blade.php" file, which includes some stuff that will always be visible.. like sidebar, login auth stuff and so on.
Now adding stuff to this is no problem. But what I want is a separate .php file that is loaded in the main content area of the app.blade.php when I go to a certain URL, let's call it "mypage.com/newpage". (Essentially, I want a link in the sidebar to load this new content.)
So my custom content should appear in the main content area, but the standard sidebar, etc, should still be there. I'm guessing it's something with routes, but... How do I proceed? Which files do I edit? What do I add and where? I already got my new HTML and Javascript code ready - I simply need to add it into the Laravel project the right way.
Suppose , bellow code is your app.blade.php file which you want to inherit.
<html>
<head>
<title>App Name - #yield('title')</title>
</head>
<body>
#section('sidebar')
This is the master sidebar.
#show
<div class="container">
#yield('content')
</div>
</body>
</html>
and you want to load the app.blade.php file here. You need to extends the page and declare the sections like this.
#extends('app')
#section('title', 'Page Title')
#section('sidebar')
#parent
<p>This is appended to the master sidebar.</p>
#endsection
#section('content')
<p>This is my body content.</p>
#endsection
Extending a layout on laravel This may help you.
What you're looking for is template inheritance. You create a layout template that you use as the main layout and your pages inherit that main layout template. See the Laravel Blade documentation: https://laravel.com/docs/5.2/blade#template-inheritance

Laravel blade: Can you yield a default partial

If I have a layout called RightSideBar.blade.php in Laravel blade, one area yield('content') and the other yield('sidebar').
Is there a built in way to display a default partial if the view that is extending RightSideBar does not have a section('sidebar')?
I know you can pass a value by default, just wondering if there is a way to make default a partial.
Yes you can pass a default
Looking at the documentation
#yield('sidebar', 'Default Content');
Which basically puts a default output when the child template does not have #section('sidebar')
Most of the time we want multiple line default content, we can use this syntax:
#section('section')
Default content
#show
For example I have this in the template file:
#section('customlayout')
<article class="content">
#yield('content')
</article>
#show
You can see the difference between #show and #stop/#endsection: the above code is equivalent to the one below:
#section('customlayout')
<article class="content">
#yield('content')
</article>
#stop
#yield('customlayout')
In the other view files I can either set the content only:
#section('content')
<p>Welcome</p>
#stop
Or I can also set a different layout:
#section('content')
<p>Welcome</p>
#stop
#section('defaultlayout')
<div>
#yield('content')
</div>
#stop
The #stop is equivalent as the #endsection.
Although the docs specifies a default only as a string you can in fact pass a view
#yield('sidebar', \View::make('defaultSidebar'))
Laravel 5.2 added a #hasSection directive that checks if a section is defined in a view.
It's not mentioned in 5.3 or 5.4 docs for some reason.
#hasSection('sidebar')
#yield('sidebar')
#else
#yield('default-sidebar')
#endif
Tested in Laravel 8:
#yield can have default content as a second parameter. It can either be a string or a view file
// user-layout.blade.php
#yield('header', View::make('layouts.header'))
You can now override this "header" with section
#section('header')
<div>New Header</div>
#endsection
//// OR - you can also pass a view file as a second parameter //////
#section('header', View::make('layouts.new-header'))

Categories