10fc320cc8
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)
94 lines
2.5 KiB
JavaScript
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;
|