mirror of
https://github.com/harttle/liquidjs.git
synced 2026-10-03 09:05:14 -07:00
refactor: more consistent tags to make it easier to iterate over, #524
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
# LiquidJS for Node.js
|
||||||
|
|
||||||
|
## Get Started
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd demo/nodejs
|
||||||
|
npm install
|
||||||
|
npm start
|
||||||
|
```
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Output, Template, Tag } from 'liquidjs'
|
||||||
|
import { isLayoutTag, isIfTag, isUnlessTag, isLiquidTag, isCaseTag, isCaptureTag, isTablerowTag, isForTag } from './type-guards'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iterate over all `{{ output }}`
|
||||||
|
*/
|
||||||
|
export function * getOutputs (templates: Template[]): Generator<Output, void> {
|
||||||
|
for (const template of templates) {
|
||||||
|
if (template instanceof Tag) {
|
||||||
|
if (isIfTag(template) || isUnlessTag(template) || isCaseTag(template)) {
|
||||||
|
for (const branch of template.branches) {
|
||||||
|
yield * getOutputs(branch.templates)
|
||||||
|
}
|
||||||
|
yield * getOutputs(template.elseTemplates)
|
||||||
|
} else if (isForTag(template)) {
|
||||||
|
yield * getOutputs(template.templates)
|
||||||
|
yield * getOutputs(template.elseTemplates)
|
||||||
|
} else if (isLiquidTag(template) || isCaptureTag(template) || isTablerowTag(template) || isLayoutTag(template)) {
|
||||||
|
yield * getOutputs(template.templates)
|
||||||
|
}
|
||||||
|
} else if (template instanceof Output) {
|
||||||
|
yield template
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { Liquid } from 'liquidjs'
|
||||||
|
import { getOutputs } from './get-outputs'
|
||||||
|
|
||||||
|
const engine = new Liquid({
|
||||||
|
root: __dirname,
|
||||||
|
extname: '.liquid'
|
||||||
|
})
|
||||||
|
|
||||||
|
const templates = engine.parseFileSync('todolist')
|
||||||
|
|
||||||
|
for (const output of getOutputs(templates)) {
|
||||||
|
const token = output.token
|
||||||
|
const [line, col] = token.getPosition()
|
||||||
|
const text = token.getText()
|
||||||
|
console.log(`[${line}:${col}] ${text}`)
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "liquidjs-demo-template",
|
||||||
|
"private": true,
|
||||||
|
"description": "liquid template parsing",
|
||||||
|
"main": "index.ts",
|
||||||
|
"scripts": {
|
||||||
|
"start": "ts-node index.ts"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"liquidjs": "latest",
|
||||||
|
"ts-node": "^8.10.2",
|
||||||
|
"typescript": "^4.2.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^14.14.37"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{% layout 'html.liquid' %}
|
||||||
|
|
||||||
|
<h1>{{ title | capitalize }}</h1>
|
||||||
|
<a>
|
||||||
|
{% if authed %} Sign out {{ username }}
|
||||||
|
{% else %} Sign in
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
<ul>
|
||||||
|
{% for todo in todos %}
|
||||||
|
<p>{{ todo }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"types": [
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { LayoutTag, ForTag, LiquidTag, CaptureTag, CaseTag, UnlessTag, TablerowTag, Tag, IfTag } from 'liquidjs'
|
||||||
|
|
||||||
|
export function isIfTag (tag: Tag): tag is IfTag {
|
||||||
|
return tag.name === 'if'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isUnlessTag (tag: Tag): tag is UnlessTag {
|
||||||
|
return tag.name === 'unless'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isLiquidTag (tag: Tag): tag is LiquidTag {
|
||||||
|
return tag.name === 'liquid'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isCaseTag (tag: Tag): tag is CaseTag {
|
||||||
|
return tag.name === 'case'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isCaptureTag (tag: Tag): tag is CaptureTag {
|
||||||
|
return tag.name === 'capture'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTablerowTag (tag: Tag): tag is TablerowTag {
|
||||||
|
return tag.name === 'tablerow'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isForTag (tag: Tag): tag is ForTag {
|
||||||
|
return tag.name === 'for'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isLayoutTag (tag: Tag): tag is LayoutTag {
|
||||||
|
return tag.name === 'layout'
|
||||||
|
}
|
||||||
+2
-2
@@ -6,10 +6,10 @@ export { Drop } from './drop'
|
|||||||
export { Emitter } from './emitters'
|
export { Emitter } from './emitters'
|
||||||
export { defaultOperators, Operators, evalToken, evalQuotedToken, Expression, isFalsy, isTruthy } from './render'
|
export { defaultOperators, Operators, evalToken, evalQuotedToken, Expression, isFalsy, isTruthy } from './render'
|
||||||
export { Context, Scope } from './context'
|
export { Context, Scope } from './context'
|
||||||
export { Value, Hash, Template, FilterImplOptions, Tag, Filter } from './template'
|
export { Value, Hash, Template, FilterImplOptions, Tag, Filter, Output } from './template'
|
||||||
export { Token, TopLevelToken, TagToken, ValueToken } from './tokens'
|
export { Token, TopLevelToken, TagToken, ValueToken } from './tokens'
|
||||||
export { TokenKind, Tokenizer, ParseStream } from './parser'
|
export { TokenKind, Tokenizer, ParseStream } from './parser'
|
||||||
export { filters } from './filters'
|
export { filters } from './filters'
|
||||||
export { tags } from './tags'
|
export * from './tags'
|
||||||
export { defaultOptions } from './liquid-options'
|
export { defaultOptions } from './liquid-options'
|
||||||
export { Liquid } from './liquid'
|
export { Liquid } from './liquid'
|
||||||
|
|||||||
+5
-5
@@ -4,8 +4,8 @@ import { BlockDrop } from '../drop'
|
|||||||
import { Liquid, TagToken, TopLevelToken, Template, Context, Emitter, Tag } from '..'
|
import { Liquid, TagToken, TopLevelToken, Template, Context, Emitter, Tag } from '..'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
private block: string
|
block: string
|
||||||
private tpls: Template[] = []
|
templates: Template[] = []
|
||||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(token, remainTokens, liquid)
|
super(token, remainTokens, liquid)
|
||||||
const match = /\w+/.exec(token.args)
|
const match = /\w+/.exec(token.args)
|
||||||
@@ -14,7 +14,7 @@ export default class extends Tag {
|
|||||||
const token = remainTokens.shift()!
|
const token = remainTokens.shift()!
|
||||||
if (isTagToken(token) && token.name === 'endblock') return
|
if (isTagToken(token) && token.name === 'endblock') return
|
||||||
const template = liquid.parser.parseToken(token, remainTokens)
|
const template = liquid.parser.parseToken(token, remainTokens)
|
||||||
this.tpls.push(template)
|
this.templates.push(template)
|
||||||
}
|
}
|
||||||
throw new Error(`tag ${token.getText()} not closed`)
|
throw new Error(`tag ${token.getText()} not closed`)
|
||||||
}
|
}
|
||||||
@@ -29,12 +29,12 @@ export default class extends Tag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getBlockRender (ctx: Context) {
|
private getBlockRender (ctx: Context) {
|
||||||
const { liquid, tpls } = this
|
const { liquid, templates } = this
|
||||||
const renderChild = ctx.getRegister('blocks')[this.block]
|
const renderChild = ctx.getRegister('blocks')[this.block]
|
||||||
const renderCurrent = function * (superBlock: BlockDrop, emitter: Emitter) {
|
const renderCurrent = function * (superBlock: BlockDrop, emitter: Emitter) {
|
||||||
// add {{ block.super }} support when rendering
|
// add {{ block.super }} support when rendering
|
||||||
ctx.push({ block: superBlock })
|
ctx.push({ block: superBlock })
|
||||||
yield liquid.renderer.renderTemplates(tpls, ctx, emitter)
|
yield liquid.renderer.renderTemplates(templates, ctx, emitter)
|
||||||
ctx.pop()
|
ctx.pop()
|
||||||
}
|
}
|
||||||
return renderChild
|
return renderChild
|
||||||
|
|||||||
+2
-2
@@ -3,8 +3,8 @@ import { evalQuotedToken } from '../render'
|
|||||||
import { isTagToken } from '../util'
|
import { isTagToken } from '../util'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
private variable: string
|
variable: string
|
||||||
private templates: Template[] = []
|
templates: Template[] = []
|
||||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(tagToken, remainTokens, liquid)
|
super(tagToken, remainTokens, liquid)
|
||||||
const tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operators)
|
const tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operators)
|
||||||
|
|||||||
+10
-10
@@ -1,12 +1,12 @@
|
|||||||
import { ValueToken, Liquid, Tokenizer, toValue, evalToken, Value, Emitter, TagToken, TopLevelToken, Context, Template, Tag, ParseStream } from '..'
|
import { ValueToken, Liquid, Tokenizer, toValue, evalToken, Value, Emitter, TagToken, TopLevelToken, Context, Template, Tag, ParseStream } from '..'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
private cond: Value
|
value: Value
|
||||||
private cases: { val?: ValueToken, templates: Template[] }[] = []
|
branches: { value?: ValueToken, templates: Template[] }[] = []
|
||||||
private elseTemplates: Template[] = []
|
elseTemplates: Template[] = []
|
||||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(tagToken, remainTokens, liquid)
|
super(tagToken, remainTokens, liquid)
|
||||||
this.cond = new Value(tagToken.args, this.liquid)
|
this.value = new Value(tagToken.args, this.liquid)
|
||||||
this.elseTemplates = []
|
this.elseTemplates = []
|
||||||
|
|
||||||
let p: Template[] = []
|
let p: Template[] = []
|
||||||
@@ -18,8 +18,8 @@ export default class extends Tag {
|
|||||||
|
|
||||||
while (!tokenizer.end()) {
|
while (!tokenizer.end()) {
|
||||||
const value = tokenizer.readValue()
|
const value = tokenizer.readValue()
|
||||||
this.cases.push({
|
this.branches.push({
|
||||||
val: value,
|
value: value,
|
||||||
templates: p
|
templates: p
|
||||||
})
|
})
|
||||||
tokenizer.readTo(',')
|
tokenizer.readTo(',')
|
||||||
@@ -37,10 +37,10 @@ export default class extends Tag {
|
|||||||
|
|
||||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
|
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
|
||||||
const r = this.liquid.renderer
|
const r = this.liquid.renderer
|
||||||
const cond = toValue(yield this.cond.value(ctx, ctx.opts.lenientIf))
|
const value = toValue(yield this.value.value(ctx, ctx.opts.lenientIf))
|
||||||
for (const branch of this.cases) {
|
for (const branch of this.branches) {
|
||||||
const val = yield evalToken(branch.val, ctx, ctx.opts.lenientIf)
|
const target = yield evalToken(branch.value, ctx, ctx.opts.lenientIf)
|
||||||
if (val === cond) {
|
if (target === value) {
|
||||||
yield r.renderTemplates(branch.templates, ctx, emitter)
|
yield r.renderTemplates(branch.templates, ctx, emitter)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -7,11 +7,11 @@ const MODIFIERS = ['offset', 'limit', 'reversed']
|
|||||||
type valueof<T> = T[keyof T]
|
type valueof<T> = T[keyof T]
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
private variable: string
|
variable: string
|
||||||
private collection: ValueToken
|
collection: ValueToken
|
||||||
private hash: Hash
|
hash: Hash
|
||||||
private templates: Template[]
|
templates: Template[]
|
||||||
private elseTemplates: Template[]
|
elseTemplates: Template[]
|
||||||
|
|
||||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(token, remainTokens, liquid)
|
super(token, remainTokens, liquid)
|
||||||
|
|||||||
+7
-7
@@ -1,19 +1,19 @@
|
|||||||
import { Liquid, Tag, Value, Emitter, isTruthy, TagToken, TopLevelToken, Context, Template } from '..'
|
import { Liquid, Tag, Value, Emitter, isTruthy, TagToken, TopLevelToken, Context, Template } from '..'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
private branches: { predicate: Value, templates: Template[] }[] = []
|
branches: { value: Value, templates: Template[] }[] = []
|
||||||
private elseTemplates: Template[] = []
|
elseTemplates: Template[] = []
|
||||||
|
|
||||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(tagToken, remainTokens, liquid)
|
super(tagToken, remainTokens, liquid)
|
||||||
let p
|
let p
|
||||||
liquid.parser.parseStream(remainTokens)
|
liquid.parser.parseStream(remainTokens)
|
||||||
.on('start', () => this.branches.push({
|
.on('start', () => this.branches.push({
|
||||||
predicate: new Value(tagToken.args, this.liquid),
|
value: new Value(tagToken.args, this.liquid),
|
||||||
templates: (p = [])
|
templates: (p = [])
|
||||||
}))
|
}))
|
||||||
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
||||||
predicate: new Value(token.args, this.liquid),
|
value: new Value(token.args, this.liquid),
|
||||||
templates: (p = [])
|
templates: (p = [])
|
||||||
}))
|
}))
|
||||||
.on('tag:else', () => (p = this.elseTemplates))
|
.on('tag:else', () => (p = this.elseTemplates))
|
||||||
@@ -26,9 +26,9 @@ export default class extends Tag {
|
|||||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, string> {
|
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, string> {
|
||||||
const r = this.liquid.renderer
|
const r = this.liquid.renderer
|
||||||
|
|
||||||
for (const { predicate, templates } of this.branches) {
|
for (const { value, templates } of this.branches) {
|
||||||
const value = yield predicate.value(ctx, ctx.opts.lenientIf)
|
const v = yield value.value(ctx, ctx.opts.lenientIf)
|
||||||
if (isTruthy(value, ctx)) {
|
if (isTruthy(v, ctx)) {
|
||||||
yield r.renderTemplates(templates, ctx, emitter)
|
yield r.renderTemplates(templates, ctx, emitter)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-22
@@ -1,26 +1,48 @@
|
|||||||
import assign from './assign'
|
import AssignTag from './assign'
|
||||||
import For from './for'
|
import ForTag from './for'
|
||||||
import capture from './capture'
|
import CaptureTag from './capture'
|
||||||
import Case from './case'
|
import CaseTag from './case'
|
||||||
import comment from './comment'
|
import CommentTag from './comment'
|
||||||
import include from './include'
|
import IncludeTag from './include'
|
||||||
import render from './render'
|
import RenderTag from './render'
|
||||||
import decrement from './decrement'
|
import DecrementTag from './decrement'
|
||||||
import cycle from './cycle'
|
import CycleTag from './cycle'
|
||||||
import If from './if'
|
import IfTag from './if'
|
||||||
import increment from './increment'
|
import IncrementTag from './increment'
|
||||||
import layout from './layout'
|
import LayoutTag from './layout'
|
||||||
import block from './block'
|
import BlockTag from './block'
|
||||||
import raw from './raw'
|
import RawTag from './raw'
|
||||||
import tablerow from './tablerow'
|
import TablerowTag from './tablerow'
|
||||||
import unless from './unless'
|
import UnlessTag from './unless'
|
||||||
import Break from './break'
|
import BreakTag from './break'
|
||||||
import Continue from './continue'
|
import ContinueTag from './continue'
|
||||||
import echo from './echo'
|
import EchoTag from './echo'
|
||||||
import liquid from './liquid'
|
import LiquidTag from './liquid'
|
||||||
import inlineComment from './inline-comment'
|
import InlineCommentTag from './inline-comment'
|
||||||
import type { TagClass } from '../template/tag'
|
import type { TagClass } from '../template/tag'
|
||||||
|
|
||||||
export const tags: Record<string, TagClass> = {
|
export const tags: Record<string, TagClass> = {
|
||||||
assign, 'for': For, capture, 'case': Case, comment, include, render, decrement, increment, cycle, 'if': If, layout, block, raw, tablerow, unless, 'break': Break, 'continue': Continue, echo, liquid, '#': inlineComment
|
assign: AssignTag,
|
||||||
|
'for': ForTag,
|
||||||
|
capture: CaptureTag,
|
||||||
|
'case': CaseTag,
|
||||||
|
comment: CommentTag,
|
||||||
|
include: IncludeTag,
|
||||||
|
render: RenderTag,
|
||||||
|
decrement: DecrementTag,
|
||||||
|
increment: IncrementTag,
|
||||||
|
cycle: CycleTag,
|
||||||
|
'if': IfTag,
|
||||||
|
layout: LayoutTag,
|
||||||
|
block: BlockTag,
|
||||||
|
raw: RawTag,
|
||||||
|
tablerow: TablerowTag,
|
||||||
|
unless: UnlessTag,
|
||||||
|
'break': BreakTag,
|
||||||
|
'continue': ContinueTag,
|
||||||
|
echo: EchoTag,
|
||||||
|
liquid: LiquidTag,
|
||||||
|
'#': InlineCommentTag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { AssignTag, ForTag, CaptureTag, CaseTag, CommentTag, IncludeTag, RenderTag, DecrementTag, IncrementTag, CycleTag, IfTag, LayoutTag, BlockTag, RawTag, TablerowTag, UnlessTag, BreakTag, ContinueTag, EchoTag, LiquidTag, InlineCommentTag }
|
||||||
|
|||||||
+9
-9
@@ -4,23 +4,23 @@ import { parseFilePath, renderFilePath, ParsedFileName } from './render'
|
|||||||
import { BlankDrop } from '../drop'
|
import { BlankDrop } from '../drop'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
private hash: Hash
|
args: Hash
|
||||||
private tpls: Template[]
|
templates: Template[]
|
||||||
private file?: ParsedFileName
|
file?: ParsedFileName
|
||||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(token, remainTokens, liquid)
|
super(token, remainTokens, liquid)
|
||||||
const tokenizer = new Tokenizer(token.args, this.liquid.options.operators)
|
const tokenizer = new Tokenizer(token.args, this.liquid.options.operators)
|
||||||
this.file = parseFilePath(tokenizer, this.liquid)
|
this.file = parseFilePath(tokenizer, this.liquid)
|
||||||
this['currentFile'] = token.file
|
this['currentFile'] = token.file
|
||||||
this.hash = new Hash(tokenizer.remaining())
|
this.args = new Hash(tokenizer.remaining())
|
||||||
this.tpls = this.liquid.parser.parseTokens(remainTokens)
|
this.templates = this.liquid.parser.parseTokens(remainTokens)
|
||||||
}
|
}
|
||||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
|
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
|
||||||
const { liquid, hash, file } = this
|
const { liquid, args, file } = this
|
||||||
const { renderer } = liquid
|
const { renderer } = liquid
|
||||||
if (file === undefined) {
|
if (file === undefined) {
|
||||||
ctx.setRegister('blockMode', BlockMode.OUTPUT)
|
ctx.setRegister('blockMode', BlockMode.OUTPUT)
|
||||||
yield renderer.renderTemplates(this.tpls, ctx, emitter)
|
yield renderer.renderTemplates(this.templates, ctx, emitter)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const filepath = (yield renderFilePath(this.file, ctx, liquid)) as string
|
const filepath = (yield renderFilePath(this.file, ctx, liquid)) as string
|
||||||
@@ -29,7 +29,7 @@ export default class extends Tag {
|
|||||||
|
|
||||||
// render remaining contents and store rendered results
|
// render remaining contents and store rendered results
|
||||||
ctx.setRegister('blockMode', BlockMode.STORE)
|
ctx.setRegister('blockMode', BlockMode.STORE)
|
||||||
const html = yield renderer.renderTemplates(this.tpls, ctx)
|
const html = yield renderer.renderTemplates(this.templates, ctx)
|
||||||
const blocks = ctx.getRegister('blocks')
|
const blocks = ctx.getRegister('blocks')
|
||||||
|
|
||||||
// set whole content to anonymous block if anonymous doesn't specified
|
// set whole content to anonymous block if anonymous doesn't specified
|
||||||
@@ -37,7 +37,7 @@ export default class extends Tag {
|
|||||||
ctx.setRegister('blockMode', BlockMode.OUTPUT)
|
ctx.setRegister('blockMode', BlockMode.OUTPUT)
|
||||||
|
|
||||||
// render the layout file use stored blocks
|
// render the layout file use stored blocks
|
||||||
ctx.push((yield hash.render(ctx)) as Scope)
|
ctx.push((yield args.render(ctx)) as Scope)
|
||||||
yield renderer.renderTemplates(templates, ctx, emitter)
|
yield renderer.renderTemplates(templates, ctx, emitter)
|
||||||
ctx.pop()
|
ctx.pop()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,14 +1,14 @@
|
|||||||
import { Template, Tokenizer, Emitter, Liquid, TopLevelToken, TagToken, Context, Tag } from '..'
|
import { Template, Tokenizer, Emitter, Liquid, TopLevelToken, TagToken, Context, Tag } from '..'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
private tpls: Template[]
|
templates: Template[]
|
||||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(token, remainTokens, liquid)
|
super(token, remainTokens, liquid)
|
||||||
const tokenizer = new Tokenizer(token.args, this.liquid.options.operators)
|
const tokenizer = new Tokenizer(token.args, this.liquid.options.operators)
|
||||||
const tokens = tokenizer.readLiquidTagTokens(this.liquid.options)
|
const tokens = tokenizer.readLiquidTagTokens(this.liquid.options)
|
||||||
this.tpls = this.liquid.parser.parseTokens(tokens)
|
this.templates = this.liquid.parser.parseTokens(tokens)
|
||||||
}
|
}
|
||||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, unknown> {
|
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, unknown> {
|
||||||
yield this.liquid.renderer.renderTemplates(this.tpls, ctx, emitter)
|
yield this.liquid.renderer.renderTemplates(this.templates, ctx, emitter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import { TablerowloopDrop } from '../drop/tablerowloop-drop'
|
|||||||
import { Tokenizer } from '../parser/tokenizer'
|
import { Tokenizer } from '../parser/tokenizer'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
private variable: string
|
variable: string
|
||||||
private hash: Hash
|
args: Hash
|
||||||
private templates: Template[]
|
templates: Template[]
|
||||||
private collection: ValueToken
|
collection: ValueToken
|
||||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(tagToken, remainTokens, liquid)
|
super(tagToken, remainTokens, liquid)
|
||||||
const tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operators)
|
const tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operators)
|
||||||
@@ -23,7 +23,7 @@ export default class extends Tag {
|
|||||||
|
|
||||||
this.variable = variable.content
|
this.variable = variable.content
|
||||||
this.collection = collectionToken
|
this.collection = collectionToken
|
||||||
this.hash = new Hash(tokenizer.remaining())
|
this.args = new Hash(tokenizer.remaining())
|
||||||
this.templates = []
|
this.templates = []
|
||||||
|
|
||||||
let p
|
let p
|
||||||
@@ -40,12 +40,12 @@ export default class extends Tag {
|
|||||||
|
|
||||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, unknown> {
|
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, unknown> {
|
||||||
let collection = toEnumerable(yield evalToken(this.collection, ctx))
|
let collection = toEnumerable(yield evalToken(this.collection, ctx))
|
||||||
const hash = (yield this.hash.render(ctx)) as Record<string, any>
|
const args = (yield this.args.render(ctx)) as Record<string, any>
|
||||||
const offset = hash.offset || 0
|
const offset = args.offset || 0
|
||||||
const limit = (hash.limit === undefined) ? collection.length : hash.limit
|
const limit = (args.limit === undefined) ? collection.length : args.limit
|
||||||
|
|
||||||
collection = collection.slice(offset, offset + limit)
|
collection = collection.slice(offset, offset + limit)
|
||||||
const cols = hash.cols || collection.length
|
const cols = args.cols || collection.length
|
||||||
|
|
||||||
const r = this.liquid.renderer
|
const r = this.liquid.renderer
|
||||||
const tablerowloop = new TablerowloopDrop(collection.length, cols, this.collection.getText(), this.variable)
|
const tablerowloop = new TablerowloopDrop(collection.length, cols, this.collection.getText(), this.variable)
|
||||||
|
|||||||
+7
-7
@@ -1,19 +1,19 @@
|
|||||||
import { Liquid, Tag, Value, TopLevelToken, Template, Emitter, isTruthy, isFalsy, Context, TagToken } from '..'
|
import { Liquid, Tag, Value, TopLevelToken, Template, Emitter, isTruthy, isFalsy, Context, TagToken } from '..'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
private branches: { predicate: Value, test: (val: any, ctx: Context) => boolean, templates: Template[] }[] = []
|
branches: { value: Value, test: (val: any, ctx: Context) => boolean, templates: Template[] }[] = []
|
||||||
private elseTemplates: Template[] = []
|
elseTemplates: Template[] = []
|
||||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(tagToken, remainTokens, liquid)
|
super(tagToken, remainTokens, liquid)
|
||||||
let p
|
let p
|
||||||
this.liquid.parser.parseStream(remainTokens)
|
this.liquid.parser.parseStream(remainTokens)
|
||||||
.on('start', () => this.branches.push({
|
.on('start', () => this.branches.push({
|
||||||
predicate: new Value(tagToken.args, this.liquid),
|
value: new Value(tagToken.args, this.liquid),
|
||||||
test: isFalsy,
|
test: isFalsy,
|
||||||
templates: (p = [])
|
templates: (p = [])
|
||||||
}))
|
}))
|
||||||
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
||||||
predicate: new Value(token.args, this.liquid),
|
value: new Value(token.args, this.liquid),
|
||||||
test: isTruthy,
|
test: isTruthy,
|
||||||
templates: (p = [])
|
templates: (p = [])
|
||||||
}))
|
}))
|
||||||
@@ -27,9 +27,9 @@ export default class extends Tag {
|
|||||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
|
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
|
||||||
const r = this.liquid.renderer
|
const r = this.liquid.renderer
|
||||||
|
|
||||||
for (const { predicate, test, templates } of this.branches) {
|
for (const { value, test, templates } of this.branches) {
|
||||||
const value = yield predicate.value(ctx, ctx.opts.lenientIf)
|
const v = yield value.value(ctx, ctx.opts.lenientIf)
|
||||||
if (test(value, ctx)) {
|
if (test(v, ctx)) {
|
||||||
yield r.renderTemplates(templates, ctx, emitter)
|
yield r.renderTemplates(templates, ctx, emitter)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { Liquid } from '../liquid'
|
|||||||
import { Filter } from './filter'
|
import { Filter } from './filter'
|
||||||
|
|
||||||
export class Output extends TemplateImpl<OutputToken> implements Template {
|
export class Output extends TemplateImpl<OutputToken> implements Template {
|
||||||
private value: Value
|
value: Value
|
||||||
public constructor (token: OutputToken, liquid: Liquid) {
|
public constructor (token: OutputToken, liquid: Liquid) {
|
||||||
super(token)
|
super(token)
|
||||||
this.value = new Value(token.content, liquid)
|
this.value = new Value(token.content, liquid)
|
||||||
|
|||||||
Reference in New Issue
Block a user