Skip to content

Commit

Permalink
Change forloop vars to loop
Browse files Browse the repository at this point in the history
closes gh-47
  • Loading branch information
paularmstrong committed Feb 12, 2012
1 parent 3d5edd8 commit c57c65e
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 36 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -33,7 +33,7 @@ Basic Example
<h1>{{ pagename|title }}</h1>
<ul>
{% for author in authors %}
<li{% if forloop.index <= 0 %} class="first"{% endif %}>{{ author }}</li>
<li{% if loop.index <= 0 %} class="first"{% endif %}>{{ author }}</li>
{% empty %}
<li>There are no authors.</li>
{% endfor %}
Expand Down
14 changes: 7 additions & 7 deletions docs/tags.md
Expand Up @@ -80,15 +80,15 @@ Wrap any section in `{% raw %}...{% endraw %}` to stop the token parser from mod
For loops have 4 special context variables accessible inside of the loop:

{% for x in y %}
{% if forloop.first %}<ul>{% endif %}
<li>{{ forloop.index }} - {{ forloop.key }}: {{ x }}</li>
{% if forloop.last %}</ul>{% endif %}
{% if loop.first %}<ul>{% endif %}
<li>{{ loop.index }} - {{ loop.key }}: {{ x }}</li>
{% if loop.last %}</ul>{% endif %}
{% endfor %}

* `forloop.index`: the zero-indexed spot in the iterator.
* `forloop.key`: if the iterator is an object, this will be the key of the current item, otherwise it will be the same as the `forloop.index`.
* `forloop.first`: `true` if the current object is the first in the object or array.
* `forloop.last`: `true` if the current object is the last in the object or array.
* `loop.index`: the zero-indexed spot in the iterator.
* `loop.key`: if the iterator is an object, this will be the key of the current item, otherwise it will be the same as the `loop.index`.
* `loop.first`: `true` if the current object is the first in the object or array.
* `loop.last`: `true` if the current object is the last in the object or array.

You can also apply filters to the object that you are iterating over.

Expand Down
2 changes: 1 addition & 1 deletion examples/express/views/people.html
Expand Up @@ -5,7 +5,7 @@
{% block body %}
<ul>
{% for person in people %}
<li><a href="/people/{{ forloop.index }}">{{ person.name }}</a> age {{ person.age }}</li>
<li><a href="/people/{{ loop.index }}">{{ person.name }}</a> age {{ person.age }}</li>
{% endfor %}
</ul>
{% endblock %}
34 changes: 17 additions & 17 deletions lib/tags.js
Expand Up @@ -242,32 +242,32 @@ exports['for'] = function (indent, parentBlock) {

operand1 = helpers.escapeVarName(operand1);

loopShared = 'forloop.index = __forloopIndex;\n' +
'forloop.first = (__forloopIndex === 0);\n' +
'forloop.last = (__forloopIndex === __forloopLength - 1);\n' +
'_context["' + operand1 + '"] = __forloopIter[forloop.key];\n' +
loopShared = 'loop.index = __loopIndex;\n' +
'loop.first = (__loopIndex === 0);\n' +
'loop.last = (__loopIndex === __loopLength - 1);\n' +
'_context["' + operand1 + '"] = __loopIter[loop.key];\n' +
parser.compile.apply(this, [indent + ' ', parentBlock]);

out = '(function () {\n' +
' var forloop = {}, __forloopKey, __forloopIndex = 0, __forloopLength = 0,' +
' var loop = {}, __loopKey, __loopIndex = 0, __loopLength = 0,' +
'__origOperand1Value = _context["' + operand1 + '"];\n' +
helpers.setVar('__forloopIter', operand2) +
helpers.setVar('__loopIter', operand2) +
' else {\n' +
' return;\n' +
' }\n' +
// Basic for loops are MUCH faster than for...in. Prefer this arrays.
' if (_.isArray(__forloopIter)) {\n' +
' __forloopIndex = 0; __forloopLength = __forloopIter.length;\n' +
' for (; __forloopIndex < __forloopLength; __forloopIndex += 1) {\n' +
' forloop.key = __forloopIndex;\n' +
' if (_.isArray(__loopIter)) {\n' +
' __loopIndex = 0; __loopLength = __loopIter.length;\n' +
' for (; __loopIndex < __loopLength; __loopIndex += 1) {\n' +
' loop.key = __loopIndex;\n' +
loopShared +
' }\n' +
' } else if (typeof __forloopIter === "object") {\n' +
' __keys = _.keys(__forloopIter);\n' +
' __forloopLength = __keys.length;\n' +
' __forloopIndex = 0;\n' +
' for (; __forloopIndex < __forloopLength; __forloopIndex += 1) {\n' +
' forloop.key = __keys[__forloopIndex];\n' +
' } else if (typeof __loopIter === "object") {\n' +
' __keys = _.keys(__loopIter);\n' +
' __loopLength = __keys.length;\n' +
' __loopIndex = 0;\n' +
' for (; __loopIndex < __loopLength; __loopIndex += 1) {\n' +
' loop.key = __keys[__loopIndex];\n' +
loopShared +
' }\n' +
' }\n' +
Expand All @@ -283,7 +283,7 @@ exports.empty = function (indent) {
throw new Error('Cannot call "empty" tag outside of "for" context.');
}

return '} if (_.keys(__forloopIter).length === 0) {\n';
return '} if (_.keys(__loopIter).length === 0) {\n';
};

/**
Expand Down
6 changes: 3 additions & 3 deletions tests/speed.js
Expand Up @@ -14,7 +14,7 @@ swig.init({
root: __dirname + '/templates'
});

tplString = '{% for foo in bar %}{{ forloop.index }} - {{ foo }}{% endfor %}';
tplString = '{% for foo in bar %}{{ loop.index }} - {{ foo }}{% endfor %}';
tplF = swig.compile(tplString);
console.time('object loop');
i = 10000;
Expand All @@ -40,8 +40,8 @@ console.log(" ~ " + Math.round(1000000 / (new Date() - d)) + " renders per se
tplString = "{% for v in array %}" +
"{% if 1 %}" +
"{% for k in v %}" +
"\n{{forloop.index}} {{k}}: " +
"{% if forloop.index in 'msafas' %}" +
"\n{{loop.index}} {{k}}: " +
"{% if loop.index in 'msafas' %}" +
"<p>Hello World {{k}}{{foo}}{{k}}{{foo}}{{k}}{{foo}}</p>" +
"{% endif %}" +
"{% endfor %}" +
Expand Down
12 changes: 6 additions & 6 deletions tests/tags.test.js
Expand Up @@ -287,7 +287,7 @@ exports['for'] = testCase({
},

variables: function (test) {
var tpl = swig.compile('{% for foo in bar %}[{{ forloop.index }}, {{ forloop.key }}]{% endfor %}');
var tpl = swig.compile('{% for foo in bar %}[{{ loop.index }}, {{ loop.key }}]{% endfor %}');
test.strictEqual(tpl({ bar: ['foo', 'bar', 'baz'] }), '[0, 0][1, 1][2, 2]', 'array loop');
test.strictEqual(tpl({ bar: { baz: 'foo', pow: 'bar', foo: 'baz' }}), '[0, baz][1, pow][2, foo]', 'object loop');
test.done();
Expand All @@ -302,21 +302,21 @@ exports['for'] = testCase({
},

index: function (test) {
var tpl = swig.compile('{% for foo in bar %}{{ forloop.index }}{% endfor %}');
var tpl = swig.compile('{% for foo in bar %}{{ loop.index }}{% endfor %}');
test.strictEqual(tpl({ bar: ['foo', 'bar', 'baz'] }), '012', 'index in object');
test.strictEqual(tpl({ bar: { baz: 'foo', pow: 'bar', foo: 'baz' }}), '012', 'index in object');
test.done();
},

first: function (test) {
var tpl = swig.compile('{% for foo in bar %}{% if forloop.first %}{{ foo }}{% endif %}{% endfor %}');
var tpl = swig.compile('{% for foo in bar %}{% if loop.first %}{{ foo }}{% endif %}{% endfor %}');
test.strictEqual(tpl({ bar: ['foo', 'bar', 'baz'] }), 'foo', 'first in array');
test.strictEqual(tpl({ bar: { baz: 'foo', pow: 'bar', foo: 'baz' }}), 'foo', 'first in object');
test.done();
},

last: function (test) {
var tpl = swig.compile('{% for foo in bar %}{% if forloop.last %}{{ foo }}{% endif %}{% endfor %}');
var tpl = swig.compile('{% for foo in bar %}{% if loop.last %}{{ foo }}{% endif %}{% endfor %}');
test.strictEqual(tpl({ bar: ['foo', 'bar', 'baz'] }), 'baz', 'last in array');
test.strictEqual(tpl({ bar: { baz: 'foo', pow: 'bar', foo: 'baz' }}), 'baz', 'last in object');
test.done();
Expand All @@ -342,8 +342,8 @@ exports['for'] = testCase({
test.done();
},

'use forloop.index in var': function (test) {
var tpl = swig.compile('{% for key in bar %}{{ foo[forloop.index] }} {% endfor %}');
'use loop.index in var': function (test) {
var tpl = swig.compile('{% for key in bar %}{{ foo[loop.index] }} {% endfor %}');
test.strictEqual(tpl({ bar: ['a', 'b', 'c'], foo: ['hi', 'and', 'bye' ]}), 'hi and bye ');
test.done();
}
Expand Down
2 changes: 1 addition & 1 deletion tests/templates/included.html
Expand Up @@ -2,7 +2,7 @@
{% if 1 %}
{% for k in v %}
<p>{{k}}: {{v}}</p>
{% if forloop.index === "af" %}
{% if loop.index === "af" %}
<p>foo: {{foo}}</p>
<p>Hello World {{k}} {{foo}}</p>
<p>array.length: {% include "included_2.html" %}</p>
Expand Down

0 comments on commit c57c65e

Please sign in to comment.