Laravel tip: enqueue script to end of body

UPDATE (7 Jan 2016): Correction to the blade @append. It doesn’t always work if you have more than a few templates appending to the section.

And so I’ve a partial blade template that contains a custom selection form, which will then be used by multiple other (page layout) templates. This allows me to change the design of the custom selection form at any time in a single location rather than going through multiple templates.

The problem is that I’ve written some JavaScript to manipulate the custom selection form on load and on click. Naturally (or lazily), the script depends on jQuery, which will only be loaded at the end of the body.

I don’t want to separate the script from my partial blade template just to insert it into the page layout templates.

Therefore, I need the custom script to be enqueued to the end, after the jQuery has loaded. I thought I could write a class that does something like WordPress’ wp_enqueue_script.

To my horror… er… surprise, Laravel’s Blade template has already catered to this kind of work using:

@section('script')
    @parent
    {{-- something --}}
@endsection

This may sound complicated, but I have 3 hierarchy of blade templates:

  • Master layout template
    • (Page layout) Single column template
      • Partial Form template
    • (Page layout) Two columns template
      • Partial Form template
  1. Master layout template
    • First I create a general master layout that defines 2 main sections: content and script.
    • <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="utf-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>Laravel 101 Template</title>
          							<link href="css/style.min.css" rel="stylesheet">
        </head>
        <body>
          @yield('content')
      
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
          @section('script')
          @show
        </body>
      </html>
  2. Page layout templates
    • Then I create various page layout templates that inherit from Master layout template.
    • It uses the partial form template to collect user input.
    • @extends('layouts.master')
      
      @section('content')
      
          @include('partials.selection-form')
      
      @stop
  3. Partial form template
    • In the partial form, I can easily append my script to the end of the Master layout template like this:
    • <div class="custom-form">
          <h3>A title</h3>
          <input value="0">
          <ul>
              <li><a href="1">Selection 1</a></li>
              <li><a href="2">Selection 2</a></li>
          </ul>
      </div>
      
      @section('script')
          @parent
          <script>
              $('.custom-form').each(function(){
                  doSomething();
              });
          </script>
      @endsection

That’s it! So simple. Love Laravel.

 

Other consideration which failed to work for me.

window.onload

I’ve tried using JavaScript’s window.onload to wait for all the resources to finish downloading before executing my script. However, due to the multiple partial templates I use within a page layout, the result varies from time to time. It seems that only the first window.onload runs properly. I cannot risk that some users may see what other users may not. It’s probably not designed to work like that.


Leave a Reply