Skip to content
Browse files

first pass at a {% set ... %} tag

  • Loading branch information...
1 parent 1320a3b commit bac8a903267abc7ce36049d8846a65e532632626 @paularmstrong committed
Showing with 73 additions and 10 deletions.
  1. +8 −0 docs/tags.md
  2. +11 −10 lib/helpers.js
  3. +23 −0 lib/tags.js
  4. +31 −0 tests/tags.test.js
View
8 docs/tags.md
@@ -113,6 +113,14 @@ Will output:
<p>Hello "you" & 'them' </p>
+### set
+
+It is also possible to set variables in templates.
+
+ {% set foo = [0, 1, 2, 3, 4, 5] %}
+ {% for num in foo %}
+ <li>{{ num }}</li>
+ {% endfor %}
## Writing Custom Tags
View
21 lib/helpers.js
@@ -74,11 +74,10 @@ exports.isValidBlockName = isValidBlockName;
* typeof foo !== 'undefined' && typeof foo.bar !== 'undefined' && typeof foo.bar.baz !== 'undefined'
*/
function check(variable, context) {
- /* 'this' inside of the render function is bound to the tag closure which is meaningless, so we can't use it.
- * '__this' is bound to the original template whose render function we called.
- * Using 'this' in the HTML templates will result in '__this.__currentContext'. This is an additional context
- * for binding data to a specific template - e.g. binding widget data.
- */
+ if (Array.isArray(variable)) {
+ return '(true)';
+ }
+
variable = variable.replace(/^this/, '__this.__currentContext');
if (isLiteral(variable)) {
@@ -111,11 +110,13 @@ exports.check = check;
* then returns a concatenation of context and the escaped variable name.
*/
exports.escape = function (variable, context) {
- /* 'this' inside of the render function is bound to the tag closure which is meaningless, so we can't use it.
- * '__this' is bound to the original template whose render function we called.
- * Using 'this' in the HTML templates will result in '__this.__currentContext'. This is an additional context
- * for binding data to a specific template - e.g. binding widget data.
- */
+ if (Array.isArray(variable)) {
+ _.each(variable, function (val, key) {
+ variable[key] = exports.escape(val, context);
+ });
+ return variable;
+ }
+
variable = variable.replace(/^this/, '__this.__currentContext');
if (isLiteral(variable)) {
View
23 lib/tags.js
@@ -247,3 +247,26 @@ exports.autoescape = function (indent) {
return parser.compile.call(this, indent);
};
exports.autoescape.ends = true;
+
+exports.set = function (indent) {
+ var varname = this.args.shift(),
+ value;
+
+ // remove '='
+ if (this.args.shift() !== '=') {
+ throw new Error('Invalid token "' + this.args[1] + '" in {% set ' + this.args[0] + ' %}. Missing "=".');
+ }
+
+ if (this.args.length > 1) {
+ try {
+ value = JSON.stringify(JSON.parse(this.args.join('')));
+ } catch (e) {
+ value = this.args.join('');
+ }
+
+ return 'var ' + varname + ' = ' + value + ';';
+ }
+
+ value = parser.parseVariable(this.args[0]);
+ return 'var ' + varname + ' = (function () { var __output = []; ' + parser.compile.call({ tokens: [value] }, indent) + ' return __output.join(""); })();';
+};
View
31 tests/tags.test.js
@@ -136,3 +136,34 @@ exports.for = testCase({
test.done();
}
});
+
+exports.set = testCase({
+ setUp: function (callback) {
+ swig.init({});
+ callback();
+ },
+
+ basic: function (test) {
+ var tmpl8 = swig.fromString('{% set foo = "bar" %} {{ foo }}');
+ test.strictEqual(tmpl8.render({}), ' bar');
+ test.done();
+ },
+
+ 'from var': function (test) {
+ var tmpl8 = swig.fromString('{% set foo = bar|lower %} {{ foo }}');
+ test.strictEqual(tmpl8.render({ bar: 'BAR' }), ' bar');
+ test.done();
+ },
+
+ 'array': function (test) {
+ var tmpl8 = swig.fromString('{% set foo = ["hi", "bye"] %} {{ foo[0] }}');
+ test.strictEqual(tmpl8.render({}), ' hi');
+ test.done();
+ },
+
+ 'object': function (test) {
+ var tmpl8 = swig.fromString('{% set foo = { bar: "bar" } %} {{ foo.bar }}');
+ test.strictEqual(tmpl8.render({}), ' bar');
+ test.done();
+ }
+});

0 comments on commit bac8a90

Please sign in to comment.
Something went wrong with that request. Please try again.