Tweet

Docs /  templates

Pages Collections

Collections of Pages

Rendering Collections of Pages

Let's say we create a project with the following structure:

src/
  layouts/default.hbs
  docs/
    index.hbs
    api.hbs
    cheatsheet.hbs
  posts/
    index.hbs
    articles.hbs
    projects.hbs
    about.hbs
    contact.hbs

Now in the Gruntfile, we configure the assemble task with two targets and a layout:

assemble: {
  options: {
    layout: 'layouts/default.hbs' 
  },
  docs: {
    files: {
      'docs/': ['src/docs/pages/*.hbs' ],
    }
  },
  blog: {
    files: {
      'blog/': ['src/blog/posts/*.hbs' ],
    }
  }
}

Inside our layout, default.hbs, we will add the pages variable to the {{#each}} block expression, and inside the block we will add the {{basename}} variable to give us the filename of each page, without the extension.

<ul > 
  {{#each  pages }} 
    <li > <a  href ="#" > {{basename }} </a > </li > 
  {{/each  }} 
</ul > 

When we build the project, pages from the docs target will render with:

<ul>
  <li><a href="#">index</a></li>
  <li><a href="#">api</a></li>
  <li><a href="#">cheatsheet</a></li>
</ul>

When we build the project, and pages from the block target will render with:

<ul>
  <li><a href="#">index</a></li>
  <li><a href="#">articles</a></li>
  <li><a href="#">projects</a></li>
  <li><a href="#">about</a></li>
  <li><a href="#">contact</a></li>
</ul>

{{#each pages}} Usage Examples

Let's say our target has two pages with the following content:

Page #1: src/templates/one.hbs

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

Page #2: src/templates/two.hbs

---
title: Home
---
<h1>{{title}}</h1>

{{page}} variable

The following templates:

{{#each  pages }} 
  {{{page }} }
{{/each  }} 

will return the concatenated "content" of each page in the target, with YFM stripped from each page, and templates returned unrendered:

<ul > 
  <li > One</li > 
  <li > Two</li > 
  <li > Three</li > 
</ul > 
<h1 > {{title }} </h1 > 

{{src}} variable

The following templates:

{{#each  pages }} 
  {{{src }} }
{{/each  }} 

will return the src path of each page in the target:

src/templates/one.hbs
src/templates/two.hbs

Using YFM with the page variable

With a couple of simple modifications to the previous example, we can have the output reflect the title of each page instead of the file name. To do so, each page must actually have a "title". So let's add a title property to the YAML front matter of each page:

---
title: Home
---

Next we will modify our template to use the title variable instead of the file name. Since we cannot use the context of each page as the first path ( see "Data, Context and Why it Works this Way" ), to make sure we get the correct title we must add the data variable, giving us access to the root of the context:

<ul > 
  {{#each  pages }} 
    <li > <a  href ="#" > {{data.title }} </a > </li > 
  {{/each  }} 
</ul > 

or this:

<ul>
  {{#each pages}}
    {{#data}}
    <li><a href="#">{{title}}</a></li>
    {{/data}}
  {{/each}}
</ul>

renders to:

<ul>
  <li><a href="#">Home</a></li><!-- text is now "home" instead of "index" -->
  <li><a href="#">Blog</a></li>
  <li><a href="#">Projects</a></li>
  <li><a href="#">About Us</a></li>
  <li><a href="#">Contact Us</a></li>
</ul>

To get a list all of the pages in a given target with certain tag, such as foo, we would "wrap" the {{#each tags}}...{{/each}} block around the {{#each pages}}...{{/each}} block, like this:

{{#each tags}}
  {{#is tag "foo"}}
  <h1>{{tag}}</h1>
  <ul>
    {{#each pages}}
      <li>{{data.title}}</li>
    {{/each}}
  </ul>
  {{/is}}
{{/each}}

Also see collections.


See the template for this page →

Find an error? Let us know →