I am Nik Butler

Knowledge Knolling

A little broken layout issue

This is going to be annoying , I had not given much thought to how the layout and handlebars presentation might break when I dont have the right amount of items to make a grid.

BrokenLayouts.png

The Layout Handlebar file for this is the index.bhs file in the layouts folder

          <div class="card-block">
            <h2>Things I have been writing about</h2>
            <div class="row">
              {{#each collections.articles}}
                 <div class="col-md-3">
                <a href="/articles/{{slugify title}}/index.html"><h3>{{title }}</h3></a>
                 <p>{{ description }}</p>
              </div>
                {{/each }}
            </div>
          </div>
        </div>

I could amend the col-md-3 value for one to make it provide few articles across the box. but as we see it does not fix the problem

BrokenLayouts-md4.png

Instead lets make it count the 4 most recent articles and the consider how I might add a archived page; lets look at the Handlebars help pageabout helpers and their usage.

Index First of all

Lets look at using index and that shows us the array index of the item iterated over in Each

          <div class="card-block">
            <h2>Things I have been writing about</h2>
            <div class="row">
              {{#each collections.articles}}
                 <div class="col-md-3">
                <a href="/articles/{{slugify title}}/index.html"><h3>{{title }} {{@index}}  </h3></a>
                 <p>{{ description }}</p>
              </div>
                {{/each }}
            </div>
          </div>
        </div>

Now we want to compare if this value is less than 7 in which case keep looping; and this is where I realise it might be easier to stop Metalsmith assembling unwanted collections so lets do the following lets amend my build.js and limit the collection to 8 ; but if i do this then I end up with failing to produce all my articles .. just the top 8 . this wont do.

so lets look at exetending our Handlebars helpers and a good answer is over on Stack Overflow - Logical operator in a handlebars.js so lets borrow that one and add it to build.js and now we have a count of 8 items ( 0 to 8 ) in our elements.

handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {

  switch (operator) {
      case '==':
          return (v1 == v2) ? options.fn(this) : options.inverse(this);
      case '===':
          return (v1 === v2) ? options.fn(this) : options.inverse(this);
      case '!=':
          return (v1 != v2) ? options.fn(this) : options.inverse(this);
      case '!==':
          return (v1 !== v2) ? options.fn(this) : options.inverse(this);
      case '<':
          return (v1 < v2) ? options.fn(this) : options.inverse(this);
      case '<=':
          return (v1 <= v2) ? options.fn(this) : options.inverse(this);
      case '>':
          return (v1 > v2) ? options.fn(this) : options.inverse(this);
      case '>=':
          return (v1 >= v2) ? options.fn(this) : options.inverse(this);
      case '&&':
          return (v1 && v2) ? options.fn(this) : options.inverse(this);
      case '||':
          return (v1 || v2) ? options.fn(this) : options.inverse(this);
      default:
          return options.inverse(this);
  }
});

This builds okay so lets update our index file

<div class="card-block">
            <h2>Things I have been writing about</h2>
            <div class="row">
              {{#each collections.articles}}
                 {{#ifCond @index '<=' 9}}
                 <div class="col-md-4">
                <a href="/articles/{{slugify title}}/index.html"><h3>{{title }}  </h3></a>
                 <p>{{ description }}</p>
              </div>
              {{/ifCond}}
              {{/each}}
            </div>
          </div>