With Laravel’s Blade templating engine, it is possible to stack multiple sections with the same name throughout a template, and yield them all together in one place. This is particularly useful if you have multiple partial views that each need to append some JavaScript to a <script> tag at the end of your page, for instance.
tl;dr
Unlike when using the @section Blade directives, there can be as many @push('name') directives with the same name as you need. Using the @stack('name') directive in place of @yield , will then pop them all out at once in a single location in your template (in reverse order).
Example usage
Suppose you’re using jQuery and that you have two partial views that each need a bit of JavaScript to run on page load:
Desired output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!-- From first partial --> <div class="must-init"> <p>Sample</p> </div> <!-- From second partial --> <div class="needs-setup"> <p>Example</p> </div> <script> $(function () { // Required by first partial $('.must-init').initialise(); // Required by second partial $('.needs-setup').setup(); )}; </script> |
Adding the scripts adjacent to the views is problematic, because likely jQuery won’t be loaded when they are executed. You could try to always remember to yield two different sections in the main layout view, but that is rather error prone.
Enter stacks
By stacking the script sections in your views, the same output that you’d create above if you weren’t using partials is easy to achieve. First, @push the script needed by each view onto the stack:
Partial template one
1 2 3 4 5 6 7 8 9 |
<!-- From first partial --> <div class="must-init"> <p>Sample</p> </div> @push('readyscripts') // Required by first partial $('.must-init').initialise(); @endpush |
Partial template two
1 2 3 4 5 6 7 8 9 |
<!-- From second partial --> <div class="needs-setup"> <p>Example</p> </div> @push('readyscripts') // Required by second partial $('.needs-setup').setup(); @endpush |
Popping the stack
You can’t use @yield to insert the pushed scripts into another template, since they weren’t defined in @section directives. Instead, simply use @stack in otherwise the same way:
1 2 3 4 5 |
<script> $(function () { @stack('readyscripts') }); </script> |
One potentially important caveat to keep in mind is that since this is indeed a stack, the last section that you push onto it will be the first to appear in your rendered output. So instead of obtaining an exact formulation of the code we initially wanted, in this example we’d end up with something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!-- From first partial --> <div class="must-init"> <p>Sample</p> </div> <!-- From second partial --> <div class="needs-setup"> <p>Example</p> </div> <script> $(function () { // Required by *second* partial $('.needs-setup').setup(); // Required by *first* partial $('.must-init').initialise(); )}; </script> |