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