Is there a way to load js into the <head> section of the page whena subview is loaded. I would like to only load specific JS files based on the view that is being called. I am using the blade template engine.
3 Answers
There is a much easier way to do this using sections and template inheritance.
- Firstly, create a master layout file, something like this:
http://paste.laravel.com/UY9 It's one I use that includes
Initializr/Bootstrap. I store this in views/layouts/frontend/ as
master.blade.php for the frontend and views/layouts/admin/ as master.blade.php for the admin and amend as necessary. - You'll notice various @section declarations ending with @show. Using @show at the end instead of @stop, allows you to override them in your other views, you'll notice I've added a @section('scripts') declaration. So, you can create a view like so:
@extends('layouts.frontend.master')
@section('scripts')
Your Scripts
@stop
@section('content')
Your content
@stop
It's that simple. This is very powerful stuff, as it gives you the ability to set a default but also override it if necessary, keeping your views very clean and minimal.
A better way to do this though would be to do:
@extends('layouts.frontend.master')
@section('head')
@parent
Your Scripts
@stop
@section('content')
Your content
@stop
Then you can remove the @section('scripts') declaration from your master layout. Using the @parent helper will allow you to append content to a section, thus keeping it's default while adding the extra content you have specified in your view.
You can also provide default content for @yield declarations, like so @yield('content', 'Default content').
Check out http://codebright.daylerees.com/blade
Comments
First make a common header layout.
app/views/layouts/header.blade.php - header layout
<!DOCTYPE html>
<html>
<head>
<title>{{ $page->title }}</title> {{-- Getting title from $page object, which is passed from route --}}
{{ HTML::style('css/common.css') }}
{{ HTML::script('js/jquery.js') }}
{{ HTML::script('js/common.js') }}
Then page specific script layout.
app/views/layouts/script-about.blade.php - about-page script layout
{{ HTML::script('js/about.js') }}
Then view for specific page.
app/views/about.blade.php - about page
@extends('layouts.master')
@section('content')
<p>About-Us page content goes here</p>
@stop
Then common footer.
app/views/layouts/footer.blade.php - footer layout
</body>
</html>
Then the main layout to render.
app/views/layouts/master.blade.php - main layout
@include('layouts.header')
@include('layouts.script-'.$page->slug) {{-- Getting page name from $page object --}}
</head>
<body>
@yield('content')
@include('layouts.footer')
And from the route, you can pass the $page variable. You may like this route,
Route::get('{slug}', function($slug) {
$page = Page::where('slug', '=', $slug)->first();
// getting the datas from Page model with pages table where slug = last uri in your address-bar
if ( is_null($page) ) { // if no page in db, call 404
App::abort(404);
}
// render the view with page details
return View::make($page->slug)->with(array('page' => $page));
});
Comments
In laravel 5.4 as stated in the document
You can simply use stacks(@stack and @push) to be able to load CSS and JS from subviews(child views).
- Add
@stackto your layout where you want JS files or CSS files to be added from child views to layout.
Here I will define two stacks in the layout file one for CSS files and one for JS files. I give the first and the second stacks arbitrary name for instance styles and scripts
we want our CSS files to be loaded in the part of layout file
<head>
@stack('styles')
</head>
and let's say we want our scripts to be added right be for the closing body tag in layout file
@stack('scripts')
</body>
- now in the child view i can easily add CSS and JS files like this
@push('styles') <style rel="stylesheet" href="{{asset('dropzone/dist/min/dropzone.min.css') }}" ></style> @endpush @push('scripts') <script src="{{ asset('dropzone/dist/min/dropzone.min.js') }}"></script> @endpush