Get first item in a sorted collection

177 Views Asked by At

Assuming I have something like:

{{#each pageElements}}
  {{#is pageElement "news"}}
    {{#withSort pages "data.posted" dir="desc"}}
      <a href="/{{relativeLink}}">
        {{formatDate data.posted "%d.%m.%Y"}}: {{data.title}}
      </a>
    {{/withSort}}
  {{/is}}
{{/each}}

How would I only show the first item that withSort spits out?

I'm think I can use the first collection helper for this (http://assemble.io/helpers/helpers-collections.html) but I haven't been able to get the syntax right.

1

There are 1 best solutions below

1
On

The helpers in handlebars-helpers that were built for grunt-assemble don't handle some of the things that you'd want to do for this specific case.

We're working on getting the dev branch published and some of these will be easier to use with handlebars subexpressions.

For now, you will probably want to make your own helper that does the sorting, then you can use first:

Make a sort.js helper file:

var get = require('get-value');

module.exports = function sort(array, field, options) {
  var arr = cloneArray(array);
  if (typeof options === 'undefined') {
    options = field;
    field = null;
    arr = arr.sort();
  } else {
    arr = arr.sort(sortBy(field));
  }

  if (options.hash && options.hash.dir === 'desc') {
    arr = arr.reverse();
  }
  return arr;
};

function cloneArray(arr) {
  var len = arr.length, i = 0;
  var results = new Array(len);
  while(i++ < len) {
    results[i] = arr[i++];
  }
  return results;
}

function sortBy(prop) {
  return function(a, b) {
    var aVal = get(a, prop);
    var bVal = get(b, prop);
    if (aVal > bVal) {
      return 1;
    } else {
      if (aVal < bVal) {
        return -1;
      }
    }
    return 0;
  }
}

Register the helper with assemble and use in the template:

{{#each pageElements}}
  {{#is pageElement "news"}}
    {{#withFirst (sort pages "data.posted" dir="desc")}}
      <a href="/{{relativeLink}}">
        {{formatDate data.posted "%d.%m.%Y"}}: {{data.title}}
      </a>
    {{/withFirst}}
  {{/is}}
{{/each}}

This should get what you need. Hope it helps.