How to yield inside an included template with laravel? - php

With Blade it seems the yield does not work with included parts. How can I fill a section defined inside an included part in the parent template?
It seems this is a known issue:
https://github.com/laravel/framework/issues/8970
template-body.blade.php
<body>
#yield('body')
<body>
template-html.blade.php
<html>
#include('template-body')
#yield('other')
</html>
foo.blade.php
#extends('template-html')
#section('body')
Hello World! (does not work)
#endsection
#section('other')
Does work
#endsection

what you are doing will give you an error. you can include pages on the template and other sub pages. it just depends on what you are doing and how you doing it. what you should have done is:
//app.layout
<!DOCTYPE html>
<html>
<head>
<title>#yield('title')</title>
<your-css-files>
#yield('styles')
<your-script files>
#yield('scripts')
</head>
<body>
#include('your page')
#yield('content')
</body>
</html>
then on your pages you do:
#extends(app.layout)
#section('content')
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
#include('your page')
#endsection
on the samepage you can call your styles and scripts as
#section('styles')
//css files
#stop
#section('scripts')
// javascript files
#stop

Related

When extending a layout all the #yield are rendered instead of the #sections chosen

When trying to use #yield and #section it does not work. With only extending the layout, all the layout is rendered, I can't choose with #section and #endsection what will be rendered.
This is for a Laravel project with HomeStead on my local machine
plantilla.blade.php is:
<html>
<head>
<title>App Name - #yield('title')</title>
</head>
<body>
<div>
#yield('sidebar')
This is the master sidebar.
</div>
<div class="container">
#yield('content')
This is another container
</div>
</body>
</html>
And the contact.blade.php is:
#extends("layouts.plantilla")
#section('content')
#endsection
When opening contact.blade.php, both sections are displayed (sidebar AND content), instead of only content, which is the section I'm actually calling.
This happens also if I just leave the first line (#extends("layouts.plantilla")
without calling any section, it will render all of its content
What could am I doing wrong here?
That's because you are yielding both content and sidebar inside your div already, so the "This is the master sidebar" and "This is another container" will always show, even if you don't use that section.
You need to change your code in main layout like this:
<html>
<head>
<title>App Name - #yield('title')</title>
</head>
<body>
#yield('sidebar')
#yield('content')
</body>
</html>
So now, if you only want to display a content of your page, you do it like this:
#extends("layouts.plantilla")
#section('content')
<div class="container">
This is another container
</div>
#endsection

Load different css/js for different views in laravel

I am new to laravel. I use laravel 5.6 . I want to use Summernote WYSIWYG editor in only one page(view). Summernote need a css and a js file. I want to load these files only in this view. How do i do that?
Here is how I tried to do that.
master.blade.php file.
<html>
#include('header')
<body>
#yield('content')
#include('footer')
</body>
</html>
editor.blade.php file
#extends('master')
#section('content')
--- Summernote editor goes here---
#endsection
#section('imports')
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.js"></script>
<!-- include summernote css/js-->
<link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote.js"></script>
<script>
$(document).ready(function() {
$('.summernote').summernote();
});
</script>
#endsection
header.blade.php
<head>
--- other css and file links ---
#yield('imports')
</head>
As you can see editor.blade.php file extends the master.blade file. And in master file I included the header.blade file which hold all of css links. So I yielded the Summernote js/css in header.blade file. But when it loaded to browser, the yielded content in header.blade file are at the beginning of the <body> tag(which should be in side the <head> tag).
I could just add those files in headr.blade.php file directly. But I wonder if there's a way to do it in this way.
I usually do this in this way, you don't use the include() blade in the master.blade since it will call to all pages regardless, just yield then in the other page just inject to that yielded section.
master.blade.js
<html>
#yield('header')
<body>
#yield('content')
#yield('footer')
</body>
</html>
header.blade.php
#extends('master')
#section('header')
--- CSS here ---
#endsection
#section('content')
--- content here ---
#endsection
#section('footer')
--- scripts here ---
#endsection

Blade syntax #extends loads second HTML view and then the first HTML view

I am new to laravel and blade template engine.
Issue: file form.blade.php
#extends('front.header')
#extends('front.footer')
Loads front/footer.blade.php first and then the contents of front/header.blade.php
Please find attached the snap shot of the View Source.
I have checked few answers in stackoverflow they say about the white space.I dont seem to have any.
Regards,
Jignesh
This is how I would recommend structuring your master template.
front._layouts.master:
<!DOCTYPE html>
<html>
<head>
#include('front._layouts.head')
</head>
<body>
<header>
#include('front._layouts.header')
</header>
<main>
#yield('content')
</main>
<footer>
#include('front._layouts.header')
</footer>
#stack('scripts')
</body>
</html>
Notice the #stack() this can come in useful when you're making a robust part of an application. Stacks allow you to push to named stacks on top of each other.
Follow this steps:
step 1:
resources\views create a file like: master.blade.php
step 2:
resources\views create a folder like: layouts
Inside layout folder create your header & footer file
step 3:
inside master.blade.php write how you design your main template like so.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- your common css here -->
#yield('partial-css')
</head>
<body>
#include('layouts.top-header')
<div class="container">
#yield('content') <!-- this is your common body -->
</div> <!-- /container -->
#include('layouts.footer')
<!-- your common js here or you also define inside the footer page -->
#yield('script') <!-- this is your individual script for all page -->
</body>
</html>
Step 4:
Now you use master page for all other pages like so index.blade.php
#extends('master')
#section('content')
<!-- Here is your main body content -->
#endsection
#section('script')
<!-- Here is your individual script content -->
#endsection
Hope you understand now how blade template works!
You cannot #extends from 2 parents. If you want to include another view, you should use #include instead
Like this :
#include('front.header')
Content
#include('front.footer')

How to tell Laravel which script files to include

How can I tell Laravel-5 which Javascript files I want to include in a template.
For example, I have my Controller with something like this:
return view('butchery', ['locations' => $locations, 'classTypes' => $classTypes]);
I have my butchery.blade.php template with my html:
#extends('app')
#section('content')
<!-- html here -->
#endsection
...and I have my app.blade.php container template with all my javascript files at the bottom. If I didn't want to include one of the javascript files in my view, how would I do that?
app.blade.php:
<!DOCTYPE HTML>
<!--[if IE 8]><html class="ie8"> <![endif]-->
<!--[if gt IE 8]><!--><html><!--<![endif]-->
<head></head>
<body>#yield('content')</body>
<script src="/js/mobile-menu.js"></script>
<!-- apply voucher code -->
<script src="/js/voucher-apply.js"></script>
</html>
You should create a section in your template where the scripts should be loaded and use this in your pages to include the required scripts.
Like so:
Template:
<html>
<head>
<title>My page</title>
</head>
<body>
<div class="container">
#yield('content')
</div>
#yield('scripts')
</body>
</html>
Page:
#extends("template")
#section('content')
<h1>Hello world!</h1>
#stop
#section('scripts')
<script src="/path/to/script.js"></script>
#stop
This way you can include the scripts on the page that are needed. Scripts that are needed through the entire template can be added under or above the #yield('scripts').
You can use roumen/asset package. It is quite easy to use and will cover all your needs. Just set default set of assets somewhere (e.g. AppServiceProvider) and then in your controller add additional js files that you need only for this particular page. This is the easies way to manage your stack of assets.
Of course you can do that manually. But hen you have to make your view composer that will share array of js files and compile them in your view. Then again make somewhere array of default js/css files and in controller methods extend them.

Exclude a view from master layout?

I have login.blade.php in views/users/ that I would like to exclude from the master layout that I have.
Instead I want the login page to be a standalone page with just the login form on it.
How may I achieve that?
Use a different layout for login page:
File app/views/login.blade.php:
#extends('layouts.standalone')
#section('content')
...
#stop
And for your other pages:
File app/views/home.blade.php:
#extends('layouts.master')
#section('content')
...
#stop
And here your layouts:
File app/views/layouts/standalone.blade.php:
<html>
<body>
This is a master layout
#yield('content')
</body>
</html>
File app/views/layouts/master.blade.php:
<html>
<body>
This is a standalone layout
#yield('content')
</body>
</html>

Categories