arrowill12
arrowill12

Reputation: 1804

load js when loading a subview in laravel

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.

Upvotes: 4

Views: 8825

Answers (3)

Gandalf
Gandalf

Reputation: 3257

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).

  1. Add @stack to 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>
  1. 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

Upvotes: 0

Gareth Daine
Gareth Daine

Reputation: 4186

There is a much easier way to do this using sections and template inheritance.

  1. 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.
  2. 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

Upvotes: 13

Anshad Vattapoyil
Anshad Vattapoyil

Reputation: 23483

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));
});

Upvotes: 2

Related Questions