From be00f1d3857e06edf01d164abbc20569518d0ba2 Mon Sep 17 00:00:00 2001 From: harttle Date: Mon, 6 Nov 2017 00:14:33 +0800 Subject: [PATCH] feature: treat top-level content as anonymous block, fixes #45 --- demo/express/views/todolist.liquid | 2 +- tags/include.js | 3 ++ tags/layout.js | 45 +++++++++++++++++++----------- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/demo/express/views/todolist.liquid b/demo/express/views/todolist.liquid index 0ad8bc98e..892ab9540 100644 --- a/demo/express/views/todolist.liquid +++ b/demo/express/views/todolist.liquid @@ -1,7 +1,7 @@ {% layout 'layout' %} diff --git a/tags/include.js b/tags/include.js index 260b18639..91f231271 100644 --- a/tags/include.js +++ b/tags/include.js @@ -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 }) } diff --git a/tags/layout.js b/tags/layout.js index 4ba84b64b..fc7af5443 100644 --- a/tags/layout.js +++ b/tags/layout.js @@ -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 + }) } }) }