I'm trying to learn Laravel by using it for one of my sites however I'm having trouble working something out.
I have a layout.blade.php file which holds all my global markup. Stuff like the header, footer etc. I'm also including some external stuff like stylesheets and scripts in <head> like this:
{{ HTML::script('js/bootstrap.min.js'); }}
However, there's some external stuff that I only want to load on certain pages. I'm including individual views from the header like this:
<div id="content">
#yield('content')
</div>
and in the views I'm extending the layout like so:
#extends('layout')
#section('content')
<h1>some content</h1>
#stop
How can I use a HTML::script type function to include stuff in my <head> from a view that extends layout.blade.php?
Thanks!
In your layout.blade.php, wrap your HTML::script calls in a #section() and #show tags, and simply extend them afterwards, in your child view, just like you did with section, but also using #parent to include the parent's content. Example:
layout.blade.php
#section('javascript')
{{ HTML::script('js/jquery.js') }}
{{ HTML::script('js/bootstrap.min.js') }}
#show
childview.blade.php
#extends('layout')
// ...
#section('javascript')
#parent
{{ HTML::script('js/customScript.js') }}
#stop
Related
How do I load page specific resource(s) using #include of the Laravel blade template engine?
Below is the content of my Master layout (master.blade.php):
<head>
#section('styles')
{{-- Some Master Styles --}}
#show
</head>
<body>
{{-- Header --}}
#section('header')
#include('header')
#show
{{-- Content --}}
#section('content')
{{-- Content for page is extending this view --}}
#show
{{-- Footer --}}
#section('footer')
#include('footer')
#show
</body>
In a given page, I make use of my master template this way:
#extends('master')
#section('styles')
#parent
{{-- Page Stylesheet --}}
#endsection
The approach above is what I use to try and load my page specific style to the <head> section.
It does not work properly as expected.
I would like to as well load other page specific resource(s) in my footer using the same approach; how can I do that effectively?
You don't need to do
#extends('master')
#section('styles')
#parent
{{-- Page Stylesheet --}}
#endsection
in your respective pages so as to load page specific stylesheets.
You should rather load page specific stylesheets for your master.blade.php file so as to keep your code dry.
To to that, you shout specify the route or expected url format of such pages, then, the appropriate stylesheet(s) to be loaded.
You can do that this way in your master.blade.php file:
#section('styles')
#if(Request::is('transactions/generate-invoice'))
#include('generate-invoice-css')
#elseif(Request::is('transactions/users'))
#include('users-css')
#endif
#show
Where generate-invoice-css.blade.php contains the stylesheet(s) you want loaded for the page content accessible at yoursite.com/transactions/generate-invoice and users-css.blade.php, that of yoursite.com/transactions/users.
For a given pattern as in: same stylesheets for pages under transactions, you can do this:
#if(Request::is('transactions*'))
using a wildcard *.
To load a given resource to a location other than the <head> section of your pages, simply use the same approach and adapt as appropriate.
To load page specific resources with an #include() from your master.blade.php, use this approach (in your master.blade.php file):
#section('styles')
#include('styles')
#show
where styles.blade.php should contain those your conditions for the appropriate resources to be loaded satisfying your requirement(s) for the purpose as in:
#if(Request::is('transactions/generate-invoice'))
#include('generate-invoice-css')
#elseif(Request::is('transactions/users'))
#include('users-css')
#endif
As the content of your styles.blade.php.
I'm just starting to learn Laravel and want to know how to go about doing the below. I'll give the code then explain.
I have a file includes/head.blade.php. this file contains things you find inside the <head>. So it contains <title>#yield('title')</title> If I now include this file in a page let say pages/about.blade.php like this #include('includes.head'), How then can I modify the <title> nested inside the include using this line #section('title', ' bout Us')
If you include the blade file like #include('includes.head') then you cannot do <title>#yield('title')</title> in head.blade.php . Correct way to do this is passing the value while including the file like :
#include('includes.head',['title'=>'About Us'])
and in head.blade.php you must do like:
<title>
#if(isset($title))
{{ $title }}
#endif
</title>
But if you extends the heade.blade.php then you can do like this :
head.blade.php
<title>#yield('title')</title>
about.blade.php
#extends('includes.head')
#section('title')
{{ "About Us" }}
#endsection
For more info Check this
I think you can use the #include like this, check this DOC.
#include('includes.head', ['title' => 'About Us'])
and the title should be print as,
<title>{{ $title }}</title>
FOR the best practice
Check the laravel blade templating feature,
you can define a master layout, extending that layout you can create new views. As like in the this DOC.
master.blade.php
<html>
<head>
<title>#yield('title')</title>
</head>
<body>
#section('sidebar')
This is the master sidebar.
#show
<div class="container">
#yield('content')
</div>
</body>
</html>
about.blade.php
#extends('master')
#section('title', 'About Us') // this will replace the **title section** in master.blade
//OR
//#section('title')
// About Us
//#endsection
#section('sidebar')
<p>This is appended to the master sidebar.</p>
#endsection
#section('content')
<p>This is my body content.</p>
#endsection
I a'm trying to yield my content from controllers. But I don't want to define again and again that I want to yield the 'Content' section
How can I archive this, so I don't need to place
#section('body')
<h1>Content</h1>
<p>More content</p>
#stop
again is every view
For example, ASP.NET MVC with RenderBody()
Use Blade templating engin, create a master layout in your `app/views/layouts' folder something like this template:
<!-- master.blade.php -->
<html>
<head></head>
<body>
<div class="container">
#yield('content')
</div>
</body>
</html>
Then in your every child view, just extend the master view, for example:
<!-- home.blade.php -->
#extends('layouts.master')
#section('body')
<h1>Content</h1>
<p>More content</p>
#stop
So, whenever you'll use something like this:
return View::make('home');
Your child view will extend the master view and content will be yielded inside the div.container.
So,
I basically have a component which requires javascript to be loaded beforehand.
master layout:
//layouts/master.blade.php
...
#yield('scripts')
...
#include('forms.search')
...
my component:
//forms/search.blade.php
#section('scripts')
some scripts here
#stop
...
what Im calling:
//main.blade.php
#extends('layouts.master')
This does not work. Section is not added to header. Am I doing something wrong or it's not possible at all with laravel?
You are trying to yield the section before including. So try this.
In your //main.blade.php
#extends('layouts.master')
And in //layouts/master.blade.php
#include('forms.search')
And //forms/search.blade.php
some scripts here
you are calling
#extends('layouts.master')
which has a
#yield('scripts')
but you are declaring the section scripts on forms/search.blade.php
so if you examine correctly, you are declaring scripts on the wrong blade template OR you have put the yield area on the wrong blade template.. because since the #yield is on the layouts/master.blade.php, it had been executed already before the #include, which does not extend anything so declaring #section there wouldn't matter.
to achieve what you want, the
#section('scripts')
some scripts here
#stop
section should be in the main.blade.php file..
if i'm gonna do that, it would be something like this:
layouts/master.blade.php
<html>
<head>
<!-- more stuff here -->
#yield('scripts')
<!-- or put it in the footer if you like -->
</head>
<body>
#yield('search-form')
#yield('content')
</body>
</html>
forms/search.blade.php
//do whatever here
main.blade.php
#extends('layouts/master')
#section('scripts')
{{ HTML::script('assets/js/search-form.js') }}
#stop
#section('search-form')
#include('forms/search')
#stop
OR remove the #yield('search-form') totally on master.blade.php and on main.blade.php do this:
#section('scripts')
{{ HTML::script('assets/js/search-form.js') }}
#stop
#section('content')
#include('forms/search')
<!-- other stuff here -->
#stop
I was having the same problem, What got it working for me was adding "#parent" to ALL my sections...
{{-- Main area where you want to "yield" --}}
#section('js')
#show
#section('js')
#parent
{{-- Code Here --}}
#stop
I have a scenario where I have a master template which defines a header section. It looks like this...
<!DOCTYPE html>
<html>
<head>
#section('header')
{{ HTML::style('css/planesaleing.css') }}
{{ HTML::script('js/jquery-1.10.1.js') }}
{{ HTML::script('js/search_Bar.js') }}
#show
</head>
<body>
<div class="planesaleing_page">
<header>
#yield('header_bar')
#yield('nav_bar')
#yield('search_bar')
</header>
<div class="main_page">
// Some more code
</div>
#yield('footer')
</div>
</body>
</html>
As you can see, I have several child views (e.g. nav_bar and search_bar). Each of these child views has an accompanying .js file. So I would like to extend the 'header' section in nav_bar like this...
#section('header')
#parent
{{ HTML::script('js/anotherjs.js') }}
#stop
and then again in search_bar like this:
#section('header')
#parent
{{ HTML::script('js/yetanotherjs.js') }}
#stop
The intention is that the final outputted html file would look like this:
#section('header')
{{ HTML::style('css/planesaleing.css') }}
{{ HTML::script('js/jquery-1.10.1.js') }}
{{ HTML::script('js/search_Bar.js') }}
{{ HTML::script('js/anotherjs.js') }}
{{ HTML::script('js/yetanotherjs.js') }}
#show
However, only the first one actually extends the header, all others after this are seemingly ignored. Is there anyway to use multiple extensions?
Any advice - much appreciated.
Firstly, when you extend a layout in a view, you start a section and then "stop". Like this:
#section('header')
#parent
{{ HTML::script('js/anotherjs.js') }}
#stop
How are you extending the layouts? I am not sure if you have multiple layouts which extend each other and are then extended by views or you have multiple views, each extending this particular layout. Now in later case, one view is not going to have any effect on the other view.
If you are using former approach, some more example code would be helpful as I think you are over writing the values at some point of time.
Hope it helps.
EDIT
when you say:
<header>
#yield('header_bar')
#yield('nav_bar')
#yield('search_bar')
</header>
You are making placeholders with three different names. So nav_bar, search_bar are not child views but they are placeholders which can be populated from your views.
Let me put it in another way. When your views extend a template, they will fill in the gaps declared in the template. So each of the 'header', 'search_bar' etc. are gaps to be filled ONCE. So if you have a view named index.blade.php, you can fill in these once. So you can have index.blade.php like this:
#section('header')
#parent
{{ HTML::script('js/anotherjs.js') }}
#stop
#section('header_bar')
#parent
{{ HTML::script('js/yetanotherjs.js') }}
#stop
#section('nav_bar')
#parent
{{ HTML::script('js/foojs.js') }}
#stop
#section('search_bar')
#parent
{{ HTML::script('js/foojs.js') }}
#stop
Now if we look at this, what it will result is:
<!DOCTYPE html>
<html>
<head>
#section('header')
{{ HTML::style('css/planesaleing.css') }}
{{ HTML::script('js/jquery-1.10.1.js') }}
{{ HTML::script('js/search_Bar.js') }}//from parent till this point
{{ HTML::script('js/anotherjs.js') }} //comes from view
#show
</head>
<body>
<div class="planesaleing_page">
<header>
{{ HTML::script('js/yetanotherjs.js') }} //comes in place of header_bar as nothing in parent
//#yield('header_bar')
{{ HTML::script('js/foojs.js') }}//comes in place of nav_bar as nothing in parent
//#yield('nav_bar')
{{ HTML::script('js/foojs.js') }}//comes in place for search_bar as nothing in parent
//#yield('search_bar')
</header>
<div class="main_page">
// Some more code
</div>
#yield('footer')
</div>
</body>
</html>
This is why just the first one seems to be extending the master. I think you should once reconsider the way you are trying to extend the master.
What can work for you is
#include('view.name') // includes a subview
However I am not sure if the sections will be cascaded from each subview or not. You can try this out.
So you will have a view called index.blade.php which looks some what like:
#extends('master')
#include('search_bar')
#include('nav_bar')
#include('foo_bar')
and then you will have separate files like search_bar.blade.php and others which will extend master and fill in the placeholders like this:
#extends('master')
#section('header')
#parent
{{ HTML::script('js/anotherjs.js') }}
#stop
I believe (havn't tested) that this should do your work. It can then cascade the inputs from all subviews and put it together like you want. So all the subviews will be populating the header section and this should be cascaded together in the final output. Try it out and if it works, GREAT !! else try a different approach to injecting the scripts.