diff --git a/core/server/helpers/foreach.js b/core/server/helpers/foreach.js
index 839c0b3a75..f7aa0fbad0 100644
--- a/core/server/helpers/foreach.js
+++ b/core/server/helpers/foreach.js
@@ -19,6 +19,8 @@ foreach = function (context, options) {
columns = options.hash.columns,
length = _.size(context),
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;
@@ -40,7 +42,7 @@ foreach = function (context, options) {
data.key = field;
data.index = index;
data.number = index + 1;
- data.first = index === 0;
+ 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;
@@ -59,13 +61,20 @@ foreach = function (context, options) {
}
function iterateCollection(context) {
- var count = 1;
+ var count = 1,
+ current = 1;
_.each(context, function (item, key) {
- if (count <= limit) {
- execIteration(key, count - 1, count === limit);
+ if (current < from) {
+ current += 1;
+ return;
+ }
+
+ if (current <= to) {
+ execIteration(key, current - 1, current === to);
}
count += 1;
+ current += 1;
});
}
diff --git a/core/server/helpers/tags.js b/core/server/helpers/tags.js
index 8310b9b83a..de56c0012e 100644
--- a/core/server/helpers/tags.js
+++ b/core/server/helpers/tags.js
@@ -21,6 +21,8 @@ tags = function (options) {
prefix = _.isString(options.hash.prefix) ? options.hash.prefix : '',
suffix = _.isString(options.hash.suffix) ? options.hash.suffix : '',
limit = options.hash.limit ? parseInt(options.hash.limit, 10) : undefined,
+ from = options.hash.from ? parseInt(options.hash.from, 10) : 1,
+ to = options.hash.to ? parseInt(options.hash.to, 10) : undefined,
output = '';
function createTagList(tags) {
@@ -37,12 +39,10 @@ tags = function (options) {
if (this.tags && this.tags.length) {
output = createTagList(this.tags);
+ from -= 1; // From uses 1-indexed, but array uses 0-indexed.
+ to = to || limit + from || this.tags.length;
- if (limit) {
- output = output.slice(0, limit);
- }
-
- output = prefix + output.join(separator) + suffix;
+ output = prefix + output.slice(from, to).join(separator) + suffix;
}
return new hbs.handlebars.SafeString(output);
diff --git a/core/test/unit/server_helpers/foreach_spec.js b/core/test/unit/server_helpers/foreach_spec.js
index 898032704f..b8e3243a5e 100644
--- a/core/test/unit/server_helpers/foreach_spec.js
+++ b/core/test/unit/server_helpers/foreach_spec.js
@@ -378,5 +378,61 @@ describe('{{#foreach}} helper', function () {
shouldCompileToExpected(templateString, arrayHash, expected);
shouldCompileToExpected(templateString, objectHash, expected);
});
+
+ it('foreach with from 2', function () {
+ var templateString = '
{{#foreach posts from="2"}}- {{title}}
{{else}}not this{{/foreach}}
',
+ expected = '';
+
+ shouldCompileToExpected(templateString, arrayHash, expected);
+ shouldCompileToExpected(templateString, objectHash, expected);
+ });
+
+ it('foreach with to 4', function () {
+ var templateString = '{{#foreach posts to="4"}}- {{title}}
{{else}}not this{{/foreach}}
',
+ expected = '';
+
+ shouldCompileToExpected(templateString, arrayHash, expected);
+ shouldCompileToExpected(templateString, objectHash, expected);
+ });
+
+ it('foreach with from 2 and to 3', function () {
+ var templateString = '{{#foreach posts from="2" to="3"}}- {{title}}
{{else}}not this{{/foreach}}
',
+ expected = '';
+
+ shouldCompileToExpected(templateString, arrayHash, expected);
+ shouldCompileToExpected(templateString, objectHash, expected);
+ });
+
+ it('foreach with from 3 and limit 2', function () {
+ var templateString = '{{#foreach posts from="3" limit="2"}}- {{title}}
{{else}}not this{{/foreach}}
',
+ expected = '';
+
+ shouldCompileToExpected(templateString, arrayHash, expected);
+ shouldCompileToExpected(templateString, objectHash, expected);
+ });
+
+ it('foreach with from 2, to 5 and limit 3', function () {
+ var templateString = '{{#foreach posts from="2" to="5" limit="3"}}- {{title}}
{{else}}not this{{/foreach}}
',
+ expected = '';
+
+ shouldCompileToExpected(templateString, arrayHash, expected);
+ shouldCompileToExpected(templateString, objectHash, expected);
+ });
+
+ it('@first in foreach with from 2 and to 4', function () {
+ var templateString = '{{#foreach posts from="2" to="4"}}{{#if @first}}- {{title}}
{{/if}}{{/foreach}}
',
+ expected = '';
+
+ shouldCompileToExpected(templateString, arrayHash, expected);
+ shouldCompileToExpected(templateString, objectHash, expected);
+ });
+
+ it('@last in foreach with from 2 and to 4', function () {
+ var templateString = '{{#foreach posts from="2" to="4"}}{{#if @last}}- {{title}}
{{/if}}{{/foreach}}
',
+ expected = '';
+
+ shouldCompileToExpected(templateString, arrayHash, expected);
+ shouldCompileToExpected(templateString, objectHash, expected);
+ });
});
});
diff --git a/core/test/unit/server_helpers/tags_spec.js b/core/test/unit/server_helpers/tags_spec.js
index d3b13ce8f6..3816066a0c 100644
--- a/core/test/unit/server_helpers/tags_spec.js
+++ b/core/test/unit/server_helpers/tags_spec.js
@@ -120,4 +120,59 @@ describe('{{tags}} helper', function () {
String(rendered).should.equal('foo');
});
+
+ it('can list tags from a specified no.', function () {
+ var tags = [{name: 'foo', slug: 'foo-bar'}, {name: 'bar', slug: 'bar'}],
+ rendered = helpers.tags.call(
+ {tags: tags},
+ {hash: {from: '2'}}
+ );
+ should.exist(rendered);
+
+ String(rendered).should.equal('bar');
+ });
+
+ it('can list tags to a specified no.', function () {
+ var tags = [{name: 'foo', slug: 'foo-bar'}, {name: 'bar', slug: 'bar'}],
+ rendered = helpers.tags.call(
+ {tags: tags},
+ {hash: {to: '1'}}
+ );
+ should.exist(rendered);
+
+ String(rendered).should.equal('foo');
+ });
+
+ it('can list tags in a range', function () {
+ var tags = [{name: 'foo', slug: 'foo-bar'}, {name: 'bar', slug: 'bar'}, {name: 'baz', slug: 'baz'}],
+ rendered = helpers.tags.call(
+ {tags: tags},
+ {hash: {from: '2', to: '3'}}
+ );
+ should.exist(rendered);
+
+ String(rendered).should.equal('bar, baz');
+ });
+
+ it('can limit no. tags and output from 2', function () {
+ var tags = [{name: 'foo', slug: 'foo-bar'}, {name: 'bar', slug: 'bar'}, {name: 'baz', slug: 'baz'}],
+ rendered = helpers.tags.call(
+ {tags: tags},
+ {hash: {from: '2', limit: '1'}}
+ );
+ should.exist(rendered);
+
+ String(rendered).should.equal('bar');
+ });
+
+ it('can list tags in a range (ignore limit)', function () {
+ var tags = [{name: 'foo', slug: 'foo-bar'}, {name: 'bar', slug: 'bar'}, {name: 'baz', slug: 'baz'}],
+ rendered = helpers.tags.call(
+ {tags: tags},
+ {hash: {from: '1', to: '3', limit: '2'}}
+ );
+ should.exist(rendered);
+
+ String(rendered).should.equal('foo, bar, baz');
+ });
});