feature: treat top-level content as anonymous block, fixes #45

This commit is contained in:
harttle
2017-11-06 00:14:33 +08:00
parent 4e132ca1c5
commit be00f1d385
3 changed files with 32 additions and 18 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{% layout 'layout' %} {% layout 'layout' %}
<ul> <ul>
{% for todo in todolist %} {% for todo in todos %}
<li>{% include 'todo' id=forloop.index %}</li> <li>{% include 'todo' id=forloop.index %}</li>
{% endfor %} {% endfor %}
</ul> </ul>
+3
View File
@@ -19,7 +19,9 @@ module.exports = function (liquid) {
var filepath = Liquid.evalValue(this.value, scope) var filepath = Liquid.evalValue(this.value, scope)
var originBlocks = scope.opts.blocks var originBlocks = scope.opts.blocks
var originBlockMode = scope.opts.blockMode
scope.opts.blocks = {} scope.opts.blocks = {}
scope.opts.blockMode = 'output'
if (this.with) { if (this.with) {
hash[filepath] = Liquid.evalValue(this.with, scope) hash[filepath] = Liquid.evalValue(this.with, scope)
@@ -32,6 +34,7 @@ module.exports = function (liquid) {
.then((html) => { .then((html) => {
scope.pop() scope.pop()
scope.opts.blocks = originBlocks scope.opts.blocks = originBlocks
scope.opts.blockMode = originBlockMode
return html return html
}) })
} }
+28 -17
View File
@@ -3,6 +3,12 @@ const Promise = require('any-promise')
const lexical = Liquid.lexical const lexical = Liquid.lexical
const assert = require('../src/util/assert.js') const assert = require('../src/util/assert.js')
/*
* blockMode:
* * "store": store rendered html into blocks
* * "output": output rendered html
*/
module.exports = function (liquid) { module.exports = function (liquid) {
liquid.registerTag('layout', { liquid.registerTag('layout', {
parse: function (token, remainTokens) { parse: function (token, remainTokens) {
@@ -16,13 +22,18 @@ module.exports = function (liquid) {
var layout = Liquid.evalValue(this.layout, scope) var layout = Liquid.evalValue(this.layout, scope)
// render the remaining tokens immediately // render the remaining tokens immediately
scope.opts.blockMode = 'store'
return liquid.renderer.renderTemplates(this.tpls, scope) return liquid.renderer.renderTemplates(this.tpls, scope)
// now register.blocks contains rendered blocks .then(html => {
.then(() => liquid.getTemplate(layout, scope.opts.root)) if (scope.opts.blocks[''] === undefined) {
scope.opts.blocks[''] = html
}
return liquid.getTemplate(layout, scope.opts.root)
})
.then(templates => { .then(templates => {
// push the hash // push the hash
scope.push(hash) scope.push(hash)
// render the parent scope.opts.blockMode = 'output'
return liquid.renderer.renderTemplates(templates, scope) return liquid.renderer.renderTemplates(templates, scope)
}) })
// pop the hash // pop the hash
@@ -36,7 +47,7 @@ module.exports = function (liquid) {
liquid.registerTag('block', { liquid.registerTag('block', {
parse: function (token, remainTokens) { parse: function (token, remainTokens) {
var match = /\w+/.exec(token.args) var match = /\w+/.exec(token.args)
this.block = match ? match[0] : 'anonymous' this.block = match ? match[0] : ''
this.tpls = [] this.tpls = []
var stream = liquid.parser.parseStream(remainTokens) var stream = liquid.parser.parseStream(remainTokens)
@@ -48,19 +59,19 @@ module.exports = function (liquid) {
stream.start() stream.start()
}, },
render: function (scope) { render: function (scope) {
var html = scope.opts.blocks[this.block] return Promise.resolve(scope.opts.blocks[this.block])
// if not defined yet .then(html => html === undefined
if (html === undefined) { // render default block
return liquid.renderer.renderTemplates(this.tpls, scope) ? liquid.renderer.renderTemplates(this.tpls, scope)
.then((partial) => { // use child-defined block
scope.opts.blocks[this.block] = partial : html)
return partial .then(html => {
}) if (scope.opts.blockMode === 'store') {
} else { scope.opts.blocks[this.block] = html
// if already defined by desendents return ''
scope.opts.blocks[this.block] = html }
return Promise.resolve(html) return html
} })
} }
}) })
} }