tags: use scope.opts insteadof scope.get('liquid')

This commit is contained in:
harttle
2017-11-04 10:46:15 +08:00
parent 329aea6bd6
commit 4e132ca1c5
8 changed files with 79 additions and 73 deletions
+3 -3
View File
@@ -3,13 +3,13 @@ var app = express()
var Liquid = require('../..')
var engine = Liquid({
root: __dirname, // for layouts and partials
root: __dirname, // for layouts and partials
extname: '.liquid'
})
app.engine('liquid', engine.express()) // register liquid engine
app.set('views', ['./partials', './views']) // specify the views directory
app.set('view engine', 'liquid') // set to default
app.set('views', ['./partials', './views']) // specify the views directory
app.set('view engine', 'liquid') // set to default
app.get('/', function (req, res) {
var todos = ['fork and clone', 'make it better', 'make a pull request']
+3 -4
View File
@@ -1,6 +1,5 @@
const app = require('./app.js');
const app = require('./app.js')
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
console.log('Example app listening on port 3000!')
})
+7 -9
View File
@@ -11,6 +11,9 @@ var Scope = {
return ctx
},
get: function (str) {
if (str === 'liquid') {
throw new Error('NO LONGER SUPPORTED: use scope.opts instread of scope.get("liquid")')
}
try {
return this.getPropertyByPath(this.scopes, str)
} catch (e) {
@@ -168,19 +171,14 @@ function matchRightBracket (str, begin) {
}
exports.factory = function (ctx, opts) {
opts = _.assign({
var defaultOptions = {
strict_variables: false,
strict_filters: false,
blocks: {},
root: []
}, opts)
ctx = _.assign(ctx, {
liquid: opts
})
}
var scope = Object.create(Scope)
scope.opts = opts
scope.scopes = [ctx]
scope.opts = _.assign(defaultOptions, opts)
scope.scopes = [ctx || {}]
return scope
}
+8 -6
View File
@@ -7,7 +7,7 @@ function initError () {
}
}
function initLiquidError (message, token) {
function initLiquidError (err, token) {
initError.call(this)
this.input = token.input
@@ -15,12 +15,14 @@ function initLiquidError (message, token) {
this.file = token.file
var context = mkContext(token.input, token.line)
this.message = mkMessage(message, token)
this.stack = context + '\n' + (this.stack || this.message)
this.message = mkMessage(err.message, token)
this.stack = context +
'\n' + (this.stack || this.message) +
(err.stack ? '\nFrom ' + err.stack : '')
}
function TokenizationError (message, token) {
initLiquidError.call(this, message, token)
initLiquidError.call(this, {message: message}, token)
}
TokenizationError.prototype = Object.create(Error.prototype)
TokenizationError.prototype.constructor = TokenizationError
@@ -29,7 +31,7 @@ function ParseError (e, token) {
_.assign(this, e)
this.originalError = e
initLiquidError.call(this, e.message, token)
initLiquidError.call(this, e, token)
}
ParseError.prototype = Object.create(Error.prototype)
ParseError.prototype.constructor = ParseError
@@ -42,7 +44,7 @@ function RenderError (e, tpl) {
_.assign(this, e)
this.originalError = e
initLiquidError.call(this, e.message, tpl.token)
initLiquidError.call(this, e, tpl.token)
}
RenderError.prototype = Object.create(Error.prototype)
RenderError.prototype.constructor = RenderError
+34 -34
View File
@@ -1,44 +1,44 @@
const Liquid = require('..');
const Promise = require('any-promise');
const lexical = Liquid.lexical;
const groupRE = new RegExp(`^(?:(${lexical.value.source})\\s*:\\s*)?(.*)$`);
const candidatesRE = new RegExp(lexical.value.source, 'g');
const assert = require('../src/util/assert.js');
const Liquid = require('..')
const Promise = require('any-promise')
const lexical = Liquid.lexical
const groupRE = new RegExp(`^(?:(${lexical.value.source})\\s*:\\s*)?(.*)$`)
const candidatesRE = new RegExp(lexical.value.source, 'g')
const assert = require('../src/util/assert.js')
module.exports = function(liquid) {
liquid.registerTag('cycle', {
module.exports = function (liquid) {
liquid.registerTag('cycle', {
parse: function(tagToken, remainTokens) {
var match = groupRE.exec(tagToken.args);
assert(match, `illegal tag: ${tagToken.raw}`);
parse: function (tagToken, remainTokens) {
var match = groupRE.exec(tagToken.args)
assert(match, `illegal tag: ${tagToken.raw}`)
this.group = match[1] || '';
var candidates = match[2];
this.group = match[1] || ''
var candidates = match[2]
this.candidates = [];
this.candidates = []
while(match = candidatesRE.exec(candidates)){
this.candidates.push(match[0]);
}
while ((match = candidatesRE.exec(candidates))) {
this.candidates.push(match[0])
}
assert(this.candidates.length, `empty candidates: ${tagToken.raw}`)
},
assert(this.candidates.length, `empty candidates: ${tagToken.raw}`);
},
render: function (scope, hash) {
var group = Liquid.evalValue(this.group, scope)
var fingerprint = `cycle:${group}:` + this.candidates.join(',')
render: function(scope, hash) {
var group = Liquid.evalValue(this.group, scope);
var fingerprint = `cycle:${group}:` + this.candidates.join(',');
var register = scope.get('liquid');
var idx = register[fingerprint];
var groups = scope.opts.groups = scope.opts.groups || {}
var idx = groups[fingerprint]
if(idx === undefined){
idx = register[fingerprint] = 0;
}
if (idx === undefined) {
idx = groups[fingerprint] = 0
}
var candidate = this.candidates[idx];
idx = (idx + 1) % this.candidates.length;
register[fingerprint] = idx;
var candidate = this.candidates[idx]
idx = (idx + 1) % this.candidates.length
groups[fingerprint] = idx
return Promise.resolve(Liquid.evalValue(candidate, scope));
}
});
};
return Promise.resolve(Liquid.evalValue(candidate, scope))
}
})
}
+4 -5
View File
@@ -18,21 +18,20 @@ module.exports = function (liquid) {
render: function (scope, hash) {
var filepath = Liquid.evalValue(this.value, scope)
var register = scope.get('liquid')
var originBlocks = register.blocks
register.blocks = {}
var originBlocks = scope.opts.blocks
scope.opts.blocks = {}
if (this.with) {
hash[filepath] = Liquid.evalValue(this.with, scope)
}
return liquid.getTemplate(filepath, register.root)
return liquid.getTemplate(filepath, scope.opts.root)
.then((templates) => {
scope.push(hash)
return liquid.renderer.renderTemplates(templates, scope)
})
.then((html) => {
scope.pop()
register.blocks = originBlocks
scope.opts.blocks = originBlocks
return html
})
}
+4 -6
View File
@@ -14,12 +14,11 @@ module.exports = function (liquid) {
},
render: function (scope, hash) {
var layout = Liquid.evalValue(this.layout, scope)
var register = scope.get('liquid')
// render the remaining tokens immediately
return liquid.renderer.renderTemplates(this.tpls, scope)
// now register.blocks contains rendered blocks
.then(() => liquid.getTemplate(layout, register.root))
.then(() => liquid.getTemplate(layout, scope.opts.root))
.then(templates => {
// push the hash
scope.push(hash)
@@ -49,18 +48,17 @@ module.exports = function (liquid) {
stream.start()
},
render: function (scope) {
var register = scope.get('liquid')
var html = register.blocks[this.block]
var html = scope.opts.blocks[this.block]
// if not defined yet
if (html === undefined) {
return liquid.renderer.renderTemplates(this.tpls, scope)
.then((partial) => {
register.blocks[this.block] = partial
scope.opts.blocks[this.block] = partial
return partial
})
} else {
// if already defined by desendents
register.blocks[this.block] = html
scope.opts.blocks[this.block] = html
return Promise.resolve(html)
}
}
+16 -6
View File
@@ -24,13 +24,23 @@ describe('tags/layout', function () {
return expect(liquid.parseAndRender(src)).to
.be.rejectedWith(/tag {%block%} not closed/)
})
it('should handle anonymous block', function () {
mock({
'/parent.html': 'X{%block%}{%endblock%}Y'
describe('anonymous block', function () {
it('should handle anonymous block', function () {
mock({
'/parent.html': 'X{%block%}{%endblock%}Y'
})
var src = '{% layout "parent.html" %}{%block%}A{%endblock%}'
return expect(liquid.parseAndRender(src)).to
.eventually.equal('XAY')
})
it('should handle top level contents as anonymous block', function () {
mock({
'/parent.html': 'X{%block%}{%endblock%}Y'
})
var src = '{% layout "parent.html" %}A'
return expect(liquid.parseAndRender(src)).to
.eventually.equal('XAY')
})
var src = '{% layout "parent.html" %}{%block%}A{%endblock%}'
return expect(liquid.parseAndRender(src)).to
.eventually.equal('XAY')
})
it('should handle named blocks', function () {
mock({