How blade @stacks make my life better

If you haven’t used @stacks yet, you might be missing out on a neat tool.

I have a site that needs an on-page anchor navigation (I’m using a scrollspy effect and position: sticky to make it useful) on product pages. The anchors are to lists of related content from elsewhere on the site; related whitepapers, related FAQs, etc. The difficulty was that each product needing this nav had a different set of related content. Some had FAQs but no whitepapers; some had whitepapers but no FAQs; some had both.

And I needed to make sure both the content AND the anchor nav matched and worked in all these cases.

Blade @stacks saved the day.

Here’s a simplified example of the product template. I stripped out a bunch of my HTML to hopefully make it easier to read. There’s some shorthand below like @if($has_whitepapers) which I’m handling with Controller in my actual theme. Just imagine it’s any test.

resources/views/partials/content-single-product.blade.php

<!-- 
Include all the templates that will populate stacks here at the top. 
They must be included before the stack is rendered. 
-->
@include('partials/resources/related-resources-faqs')
@include('partials/resources/related-resources-whitepapers')

<article @php(post_class())>
  <ul class="nav nav-pills" role="tablist">

    <!-- I want the #top link to be at the top of this list no matter what else happens -->
    <li class="nav-item"><a class="nav-link" href="#top">{{ __('Description') }}</a></li>

    <!-- Output the rest of the items by rendering the navigation stack-->
    @stack('productnav')  

  </ul>

  <header>
    <h1>{{ get_the_title() }}</h1>
  </header>
  <div class="entry-content" >

    <section id="top">
      @php(the_content())
    </section>

    <!-- Output the content stack-->
    @stack('content')

  </div>

</article>


And here’s an example of one of the templates that populates BOTH stacks from a single template include:

partials/resources/related-resources-whitepapers.blade.php


@if($has_whitepapers)

  @push('productnav')

    <!-- This gets pushed to the productnav stack -->
    <li class="nav-item"><a class="nav-link" href="#related-whitepapers">{{ __('White Papers') }}</a></li>

  @endpush

  @push('content')

    <!-- And this gets pushed to the content stack, all from the same include at the top of the other file -->
    <section id="related-whitepapers">
      <h3>{{ __('White Papers') }}</h3>

      <!-- Whatever HTML output goes with this item -->    

    </section>

  @endpush

@endif

Hopefully this is followable. If not, ask me questions. I’ve found @stacks useful for this kind of example, for footers that need a call to action depending on the page template, and things like that.

Thanks for reading!

18 Likes

Woah, cool!! Thanks for the example. Here’s a link to stacks in their documentation: https://laravel.com/docs/5.4/blade#stacks

3 Likes