Skip to content

Instantly share code, notes, and snippets.

@jonschlinkert
Last active February 3, 2018 05:55
Show Gist options
  • Save jonschlinkert/2f540cdeb3019f439534 to your computer and use it in GitHub Desktop.
Save jonschlinkert/2f540cdeb3019f439534 to your computer and use it in GitHub Desktop.
Assemble: how to add a sidebar that conditionally renders on certain pages, allowing each page to use different links

Originally written for http://stackoverflow.com/questions/24705434/assemble-dynamic-or-conditional-partials

Unique IDs

This is just one strategy, but it's simple. If you put a unique identifier in the YAML front-matter of each page it will come in handy later. This is easily done when you add a title property or any other content. slug is a good one to use because it can be used in permalinks or in conditional handlebars expressions etc. A slug should have no spaces, be lowercase, and use dashes not underscores if it might end up in permalinks.

If slug doesn't work for you, use whatever makes sense, but basename probably isn't a good one for this purpose b/c it could be index, which might belong to more than one file, and properties like title might be a sentences.

YAML front matter

Add the following to the about page:

---
title: About
slug: about
---

<h1>{{title}}</h1>

The actual sidebar partial

In a file named sidebar.hbs add something like this:

<ul class="side-nav">
{{#each .}}
  {{! `slug` is our unique identifier for each page }}
  {{#is @root.page.slug slug}}
    {{#links}}
      {{#if separator}}
      <li class="divider"></li>
      {{else}}
      <li{{#if modifier}} class="{{modifier}}"{{/if}}>
        {{#if link}} <a href="{{url}}">{{text}}</a> {{else}} {{text}} {{/if}}
      </li>
      {{/if}}
    {{/links}}
  {{/is}}
{{/each}}
</ul>

Use the sidebar partial

Add the following to the layout where you want the sidebar to be injected. The isnt block helper will ensure that the sidebar doesn't render on pages that shouldn't have it.

{{#isnt slug 'home'}}
  {{> sidebar sidebar }}
{{/isnt}}

Another approach is to add a property to the YAML front-matter that is used to decide when to use a sidebar. Something like:

{{#if sidenav}}
  {{> sidebar sidebar }}
{{/if}}

And in the front matter:

---
title: About
slug: about
sidenav: true
---

<h1>{{title}}</h1>

This is a balance, it can get out of hand if you start using this strategy for everything.

Sidebar data file

Now, create a sidebar.yml file, and add the following (with your own data obviously):

# About page
- slug: about
  links:
  - modifier: heading
    link: true
    url:  '#'
    text: Learn About GeneAware
  - link: true
    url:  '#'
    text: 'Diseases & Disorders Search'
  - separator: true
  - link: true
    url:  '#'
    text: Next Steps

# Contact page
- slug: contact
  links:
  - modifier: heading
    link: true
    url:  '#'
    text: Foo
  - link: true
    url:  '#'
    text: Bar
  - separator: true
  - link: true
    url:  '#'
    text: Baz

In case you prefer JSON, I put this together so you can pick: https://gist.github.com/jonschlinkert/f8cd6c777ca0c20d63ff.

Assemble options

Make sure you tell Assemble where the sidebar.yml data file is by defining it in the options, e.g.:

options: {
  data: ['data/sidebar.yml']
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment