Ghost/core/server/helpers/foreach.js
Hannah Wolfe 10fc320cc8 Rename confusing 'context' variables
no issue
- In Ghost, 'context' means the page or section of a blog we're currently within
when rendering a theme, e.g. 'post' or 'tag' or 'home'.
- In handlebars 'context' refers to the blob of JSON that is tied to a template.
- These two uses of the word 'context' have gotten very confusing, so I've removed all usage of 'context' within the Ghost handlebars helpers, EXCEPT where they actually refer to the current context (e.g. the is helper)
2016-02-21 22:07:15 +00:00

94 lines
2.5 KiB
JavaScript

// # Foreach Helper
// Usage: `{{#foreach data}}{{/foreach}}`
//
// Block helper designed for looping through posts
var hbs = require('express-hbs'),
_ = require('lodash'),
errors = require('../errors'),
i18n = require('../i18n'),
hbsUtils = hbs.handlebars.Utils,
foreach;
foreach = function (itemType, options) {
if (!options) {
errors.logWarn(i18n.t('warnings.helpers.foreach.iteratorNeeded'));
}
var fn = options.fn,
inverse = options.inverse,
columns = options.hash.columns,
length = _.size(itemType),
limit = parseInt(options.hash.limit, 10) || length,
from = parseInt(options.hash.from, 10) || 1,
to = parseInt(options.hash.to, 10) || (from - 1) + limit,
output = '',
data,
contextPath;
if (options.data && options.ids) {
contextPath = hbsUtils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
}
if (hbsUtils.isFunction(itemType)) {
itemType = itemType.call(this);
}
if (options.data) {
data = hbs.handlebars.createFrame(options.data);
}
function execIteration(field, index, last) {
if (data) {
data.key = field;
data.index = index;
data.number = index + 1;
data.first = index === from - 1; // From uses 1-indexed, but array uses 0-indexed.
data.last = !!last;
data.even = index % 2 === 1;
data.odd = !data.even;
data.rowStart = index % columns === 0;
data.rowEnd = index % columns === (columns - 1);
if (contextPath) {
data.contextPath = contextPath + field;
}
}
output = output + fn(itemType[field], {
data: data,
blockParams: hbsUtils.blockParams([itemType[field], field], [contextPath + field, null])
});
}
function iterateCollection(context) {
var count = 1,
current = 1;
_.each(context, function (item, key) {
if (current < from) {
current += 1;
return;
}
if (current <= to) {
execIteration(key, current - 1, current === to);
}
count += 1;
current += 1;
});
}
if (itemType && typeof itemType === 'object') {
iterateCollection(itemType);
}
if (length === 0) {
output = inverse(this);
}
return output;
};
module.exports = foreach;