feat: Support for the "render" tag #163

This commit is contained in:
Jun Yang
2019-10-27 00:06:16 +08:00
parent b82fa9ed2b
commit d5e7b047bb
7 changed files with 269 additions and 10 deletions
+2 -1
View File
@@ -4,6 +4,7 @@ import capture from './capture'
import Case from './case'
import comment from './comment'
import include from './include'
import render from './render'
import decrement from './decrement'
import cycle from './cycle'
import If from './if'
@@ -18,7 +19,7 @@ import Continue from './continue'
import { ITagImplOptions } from '../../template/tag/itag-impl-options'
const tags: { [key: string]: ITagImplOptions } = {
assign, 'for': For, capture, 'case': Case, comment, include, decrement, increment, cycle, 'if': If, layout, block, raw, tablerow, unless, 'break': Break, 'continue': Continue
assign, 'for': For, capture, 'case': Case, comment, include, render, decrement, increment, cycle, 'if': If, layout, block, raw, tablerow, unless, 'break': Break, 'continue': Continue
}
export default tags
+3 -3
View File
@@ -1,4 +1,4 @@
import { Hash, Emitter, TagToken, Token, ITagImplOptions, Context } from '../../types'
import { TagToken, Token, ITagImplOptions } from '../../types'
export default {
parse: function (tagToken: TagToken, remainTokens: Token[]) {
@@ -15,7 +15,7 @@ export default {
})
stream.start()
},
render: function (ctx: Context, hash: Hash, emitter: Emitter) {
emitter.write(this.tokens.map((token: Token) => token.raw).join(''))
render: function () {
return this.tokens.map((token: Token) => token.raw).join('')
}
} as ITagImplOptions
+50
View File
@@ -0,0 +1,50 @@
import { assert } from '../../util/assert'
import { Expression, Hash, Emitter, TagToken, Context, ITagImplOptions } from '../../types'
import { value, quotedLine } from '../../parser/lexical'
import BlockMode from '../../context/block-mode'
const staticFileRE = /[^\s,]+/
const withRE = new RegExp(`with\\s+(${value.source})`)
export default {
parse: function (token: TagToken) {
let match = staticFileRE.exec(token.args)
if (match) this.staticValue = match[0]
match = value.exec(token.args)
if (match) this.value = match[0]
match = withRE.exec(token.args)
if (match) this.with = match[1]
},
render: function * (ctx: Context, hash: Hash, emitter: Emitter) {
let filepath
if (ctx.opts.dynamicPartials) {
if (quotedLine.exec(this.value)) {
const template = this.value.slice(1, -1)
filepath = yield this.liquid._parseAndRender(template, ctx.getAll(), ctx.opts, ctx.sync)
} else {
filepath = yield new Expression(this.value).value(ctx)
}
} else {
filepath = this.staticValue
}
assert(filepath, `cannot render with empty filename`)
const originBlocks = ctx.getRegister('blocks')
const originBlockMode = ctx.getRegister('blockMode')
const childCtx = new Context({}, ctx.opts, ctx.sync)
childCtx.setRegister('blocks', {})
childCtx.setRegister('blockMode', BlockMode.OUTPUT)
if (this.with) {
hash[filepath] = yield new Expression(this.with).evaluate(ctx)
}
childCtx.push(hash)
const templates = yield this.liquid._parseFile(filepath, childCtx.opts, childCtx.sync)
yield this.liquid.renderer.renderTemplates(templates, childCtx, emitter)
childCtx.setRegister('blocks', originBlocks)
childCtx.setRegister('blockMode', originBlockMode)
}
} as ITagImplOptions