mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 12:20:40 -07:00
About halfway through converting all tags to async
This commit is contained in:
+2
-2
@@ -38,12 +38,12 @@ var render = {
|
||||
renderTag: function(template, scope, register) {
|
||||
if (template.name === 'continue') {
|
||||
scope.set('forloop.skip', true);
|
||||
return;
|
||||
return Promise.resolve('');
|
||||
}
|
||||
if (template.name === 'break') {
|
||||
scope.set('forloop.stop', true);
|
||||
scope.set('forloop.skip', true);
|
||||
return;
|
||||
return Promise.resolve('');
|
||||
}
|
||||
return template.render(scope, register);
|
||||
},
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
const lexical = require('./lexical.js');
|
||||
const Promise = require('any-promise');
|
||||
const Exp = require('./expression.js');
|
||||
const TokenizationError = require('./error.js').TokenizationError;
|
||||
|
||||
@@ -21,7 +22,7 @@ module.exports = function() {
|
||||
var reg = register[this.name];
|
||||
if(!reg) reg = register[this.name] = {};
|
||||
var obj = hash(this.token.args, scope);
|
||||
return this.tagImpl.render && this.tagImpl.render(scope, obj, reg) || '';
|
||||
return this.tagImpl.render && this.tagImpl.render(scope, obj, reg) || Promise.resolve('');
|
||||
},
|
||||
parse: function(token, tokens){
|
||||
this.type = 'tag';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var Liquid = require('..');
|
||||
var Promise = require('any-promise');
|
||||
var lexical = Liquid.lexical;
|
||||
var re = new RegExp(`(${lexical.identifier.source})\\s*=(.*)`);
|
||||
|
||||
@@ -13,6 +14,7 @@ module.exports = function(liquid) {
|
||||
},
|
||||
render: function(scope, hash) {
|
||||
scope.set(this.key, liquid.evalOutput(this.value, scope));
|
||||
return Promise.resolve('');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
var Liquid = require('..');
|
||||
var Promise = require('any-promise');
|
||||
var lexical = Liquid.lexical;
|
||||
var groupRE = new RegExp(`^(?:(${lexical.value.source})\\s*:\\s*)?(.*)$`);
|
||||
var candidatesRE = new RegExp(lexical.value.source, 'g');
|
||||
@@ -37,7 +38,7 @@ module.exports = function(liquid) {
|
||||
idx = (idx + 1) % this.candidates.length;
|
||||
register[fingerprint] = idx;
|
||||
|
||||
return Liquid.evalValue(candidate, scope);
|
||||
return Promise.resolve(Liquid.evalValue(candidate, scope));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
+42
-5
@@ -1,4 +1,6 @@
|
||||
var Liquid = require('..');
|
||||
var Promise = require('any-promise');
|
||||
var _ = require('lodash');
|
||||
var lexical = Liquid.lexical;
|
||||
var re = new RegExp(`^(${lexical.identifier.source})\\s+in\\s+` +
|
||||
`(${lexical.value.source})` +
|
||||
@@ -44,6 +46,8 @@ module.exports = function(liquid) {
|
||||
|
||||
collection = collection.slice(offset, offset + limit);
|
||||
if(this.reversed) collection.reverse();
|
||||
|
||||
var scopes = [];
|
||||
collection.some((item, i) => {
|
||||
ctx[this.variable] = item;
|
||||
ctx.forloop = {
|
||||
@@ -57,14 +61,47 @@ module.exports = function(liquid) {
|
||||
stop: false,
|
||||
skip: false
|
||||
};
|
||||
// todo: verify scope management is good here. Make sure we don't consume too many resources here with the clone.
|
||||
// Is there a simpler solution?
|
||||
scope.push(ctx);
|
||||
html += liquid.renderer.renderTemplates(this.templates, scope);
|
||||
var breakloop = scope.get('forloop.stop');
|
||||
// We are just putting together an array of the arguments we will be passing to our sequential promises
|
||||
scopes.push(_.clone(scope));
|
||||
scope.pop(ctx);
|
||||
|
||||
if (breakloop) return true;
|
||||
});
|
||||
return html;
|
||||
|
||||
// This is some pretty tricksy javascript, at least to me. Bluebird would have made this a lot easier, but
|
||||
// we are trying to not use anything that can't be done in native node Promises.
|
||||
// This basically just processes an array of promises sequentially for every argument in the array - http://webcache.googleusercontent.com/search?q=cache:rNbMUn9TPtkJ:joost.vunderink.net/blog/2014/12/15/processing-an-array-of-promises-sequentially-in-node-js/+&cd=5&hl=en&ct=clnk&gl=us
|
||||
var lastPromise = scopes.reduce((promise, scope) => {
|
||||
return promise.then(function(partial) {
|
||||
var breakloop = scope.get('forloop.stop');
|
||||
if (breakloop)
|
||||
throw new Error('forloop.stop'); // this will stop the sequential promise chain
|
||||
|
||||
html += partial;
|
||||
return liquid.renderer.renderTemplates(this.templates, scope);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error === 'forloop.stop') {
|
||||
// the error is a controlled, purposeful stop. so just return the html that we have up to this point
|
||||
return html;
|
||||
} else {
|
||||
// rethrow actual error
|
||||
throw new Error(error);
|
||||
}
|
||||
});
|
||||
}, Promise.resolve()); // start the reduce chain with a resolved Promise. After first run, the "promise" argument
|
||||
// in our reduce callback will be the returned promise from our "then" above. In this
|
||||
// case, the promise returned from liquid.renderer.renderTemplates.
|
||||
|
||||
lastPromise
|
||||
.then(() => {
|
||||
return Promise.resolve(html);
|
||||
})
|
||||
.catch((error) => {
|
||||
throw new Error(error);
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
+3
-1
@@ -1,4 +1,5 @@
|
||||
var Liquid = require('..');
|
||||
var Promise = require('any-promise');
|
||||
var lexical = Liquid.lexical;
|
||||
var re = new RegExp(`(${lexical.identifier.source})`);
|
||||
|
||||
@@ -20,7 +21,8 @@ module.exports = function(liquid) {
|
||||
stream.start();
|
||||
},
|
||||
render: function(scope, hash) {
|
||||
return this.tokens.map(token => token.raw).join('');
|
||||
var tokens = this.tokens.map(token => token.raw).join('');
|
||||
return Promise.resolve(tokens);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ module.exports = function(liquid) {
|
||||
ctx[this.variable] = item;
|
||||
scope.push(ctx);
|
||||
html += `<td class="col${col}">`;
|
||||
// todo: replace with sequential promises, see for.js
|
||||
html += liquid.renderer.renderTemplates(this.templates, scope);
|
||||
html += '</td>';
|
||||
scope.pop(ctx);
|
||||
|
||||
+7
-3
@@ -11,7 +11,11 @@ var liquid = Liquid({
|
||||
ctx, src, dst;
|
||||
|
||||
function test(src, dst) {
|
||||
expect(liquid.parseAndRender(src, ctx)).to.equal(dst);
|
||||
liquid.parseAndRender(src, ctx)
|
||||
.then((result) => {
|
||||
expect(result.to.equal(dst));
|
||||
});
|
||||
//expect(liquid.parseAndRender(src, ctx)).to.equal(dst);
|
||||
}
|
||||
|
||||
function testThrow(src, pattern) {
|
||||
@@ -203,7 +207,7 @@ describe('tags', function() {
|
||||
test('{% decrement one %}{{one}}', '0');
|
||||
});
|
||||
|
||||
it('should support tablerow', function() {
|
||||
it.only('should support tablerow', function() {
|
||||
src = '{% tablerow i in alpha cols:2 %}{{ i }}{% endtablerow %}';
|
||||
dst = '<table>' +
|
||||
'<tr class="row1"><td class="col1">a</td><td class="col2">b</td></tr>' +
|
||||
@@ -279,7 +283,7 @@ describe('tags', function() {
|
||||
expect(liquid.renderFile(filepath, ctx)).to.equal(dst);
|
||||
});
|
||||
|
||||
it.only('should support nested includes', function() {
|
||||
it('should support nested includes', function() {
|
||||
//expect(liquid.renderFile('personInfo.html', ctx)).to.equal('This is a person <p>Joe Shmoe<br/>City: Dallas</p>');
|
||||
return liquid.renderFile('personInfo.html', ctx).should.eventually.equal('This is a person <p>Joe Shmoe<br/>City: Dallas</p>')
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user