mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-17 21:40:39 -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 { defaultOperators, Operators, evalToken, evalQuotedToken, Expression, isFalsy, isTruthy } from './render'
|
||||
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 { TokenKind, Tokenizer, ParseStream } from './parser'
|
||||
export { filters } from './filters'
|
||||
export { tags } from './tags'
|
||||
export * from './tags'
|
||||
export { defaultOptions } from './liquid-options'
|
||||
export { Liquid } from './liquid'
|
||||
|
||||
+5
-5
@@ -4,8 +4,8 @@ import { BlockDrop } from '../drop'
|
||||
import { Liquid, TagToken, TopLevelToken, Template, Context, Emitter, Tag } from '..'
|
||||
|
||||
export default class extends Tag {
|
||||
private block: string
|
||||
private tpls: Template[] = []
|
||||
block: string
|
||||
templates: Template[] = []
|
||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(token, remainTokens, liquid)
|
||||
const match = /\w+/.exec(token.args)
|
||||
@@ -14,7 +14,7 @@ export default class extends Tag {
|
||||
const token = remainTokens.shift()!
|
||||
if (isTagToken(token) && token.name === 'endblock') return
|
||||
const template = liquid.parser.parseToken(token, remainTokens)
|
||||
this.tpls.push(template)
|
||||
this.templates.push(template)
|
||||
}
|
||||
throw new Error(`tag ${token.getText()} not closed`)
|
||||
}
|
||||
@@ -29,12 +29,12 @@ export default class extends Tag {
|
||||
}
|
||||
|
||||
private getBlockRender (ctx: Context) {
|
||||
const { liquid, tpls } = this
|
||||
const { liquid, templates } = this
|
||||
const renderChild = ctx.getRegister('blocks')[this.block]
|
||||
const renderCurrent = function * (superBlock: BlockDrop, emitter: Emitter) {
|
||||
// add {{ block.super }} support when rendering
|
||||
ctx.push({ block: superBlock })
|
||||
yield liquid.renderer.renderTemplates(tpls, ctx, emitter)
|
||||
yield liquid.renderer.renderTemplates(templates, ctx, emitter)
|
||||
ctx.pop()
|
||||
}
|
||||
return renderChild
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ import { evalQuotedToken } from '../render'
|
||||
import { isTagToken } from '../util'
|
||||
|
||||
export default class extends Tag {
|
||||
private variable: string
|
||||
private templates: Template[] = []
|
||||
variable: string
|
||||
templates: Template[] = []
|
||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(tagToken, remainTokens, liquid)
|
||||
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 '..'
|
||||
|
||||
export default class extends Tag {
|
||||
private cond: Value
|
||||
private cases: { val?: ValueToken, templates: Template[] }[] = []
|
||||
private elseTemplates: Template[] = []
|
||||
value: Value
|
||||
branches: { value?: ValueToken, templates: Template[] }[] = []
|
||||
elseTemplates: Template[] = []
|
||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(tagToken, remainTokens, liquid)
|
||||
this.cond = new Value(tagToken.args, this.liquid)
|
||||
this.value = new Value(tagToken.args, this.liquid)
|
||||
this.elseTemplates = []
|
||||
|
||||
let p: Template[] = []
|
||||
@@ -18,8 +18,8 @@ export default class extends Tag {
|
||||
|
||||
while (!tokenizer.end()) {
|
||||
const value = tokenizer.readValue()
|
||||
this.cases.push({
|
||||
val: value,
|
||||
this.branches.push({
|
||||
value: value,
|
||||
templates: p
|
||||
})
|
||||
tokenizer.readTo(',')
|
||||
@@ -37,10 +37,10 @@ export default class extends Tag {
|
||||
|
||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
|
||||
const r = this.liquid.renderer
|
||||
const cond = toValue(yield this.cond.value(ctx, ctx.opts.lenientIf))
|
||||
for (const branch of this.cases) {
|
||||
const val = yield evalToken(branch.val, ctx, ctx.opts.lenientIf)
|
||||
if (val === cond) {
|
||||
const value = toValue(yield this.value.value(ctx, ctx.opts.lenientIf))
|
||||
for (const branch of this.branches) {
|
||||
const target = yield evalToken(branch.value, ctx, ctx.opts.lenientIf)
|
||||
if (target === value) {
|
||||
yield r.renderTemplates(branch.templates, ctx, emitter)
|
||||
return
|
||||
}
|
||||
|
||||
+5
-5
@@ -7,11 +7,11 @@ const MODIFIERS = ['offset', 'limit', 'reversed']
|
||||
type valueof<T> = T[keyof T]
|
||||
|
||||
export default class extends Tag {
|
||||
private variable: string
|
||||
private collection: ValueToken
|
||||
private hash: Hash
|
||||
private templates: Template[]
|
||||
private elseTemplates: Template[]
|
||||
variable: string
|
||||
collection: ValueToken
|
||||
hash: Hash
|
||||
templates: Template[]
|
||||
elseTemplates: Template[]
|
||||
|
||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(token, remainTokens, liquid)
|
||||
|
||||
+7
-7
@@ -1,19 +1,19 @@
|
||||
import { Liquid, Tag, Value, Emitter, isTruthy, TagToken, TopLevelToken, Context, Template } from '..'
|
||||
|
||||
export default class extends Tag {
|
||||
private branches: { predicate: Value, templates: Template[] }[] = []
|
||||
private elseTemplates: Template[] = []
|
||||
branches: { value: Value, templates: Template[] }[] = []
|
||||
elseTemplates: Template[] = []
|
||||
|
||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(tagToken, remainTokens, liquid)
|
||||
let p
|
||||
liquid.parser.parseStream(remainTokens)
|
||||
.on('start', () => this.branches.push({
|
||||
predicate: new Value(tagToken.args, this.liquid),
|
||||
value: new Value(tagToken.args, this.liquid),
|
||||
templates: (p = [])
|
||||
}))
|
||||
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
||||
predicate: new Value(token.args, this.liquid),
|
||||
value: new Value(token.args, this.liquid),
|
||||
templates: (p = [])
|
||||
}))
|
||||
.on('tag:else', () => (p = this.elseTemplates))
|
||||
@@ -26,9 +26,9 @@ export default class extends Tag {
|
||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, string> {
|
||||
const r = this.liquid.renderer
|
||||
|
||||
for (const { predicate, templates } of this.branches) {
|
||||
const value = yield predicate.value(ctx, ctx.opts.lenientIf)
|
||||
if (isTruthy(value, ctx)) {
|
||||
for (const { value, templates } of this.branches) {
|
||||
const v = yield value.value(ctx, ctx.opts.lenientIf)
|
||||
if (isTruthy(v, ctx)) {
|
||||
yield r.renderTemplates(templates, ctx, emitter)
|
||||
return
|
||||
}
|
||||
|
||||
+44
-22
@@ -1,26 +1,48 @@
|
||||
import assign from './assign'
|
||||
import For from './for'
|
||||
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'
|
||||
import increment from './increment'
|
||||
import layout from './layout'
|
||||
import block from './block'
|
||||
import raw from './raw'
|
||||
import tablerow from './tablerow'
|
||||
import unless from './unless'
|
||||
import Break from './break'
|
||||
import Continue from './continue'
|
||||
import echo from './echo'
|
||||
import liquid from './liquid'
|
||||
import inlineComment from './inline-comment'
|
||||
import AssignTag from './assign'
|
||||
import ForTag from './for'
|
||||
import CaptureTag from './capture'
|
||||
import CaseTag from './case'
|
||||
import CommentTag from './comment'
|
||||
import IncludeTag from './include'
|
||||
import RenderTag from './render'
|
||||
import DecrementTag from './decrement'
|
||||
import CycleTag from './cycle'
|
||||
import IfTag from './if'
|
||||
import IncrementTag from './increment'
|
||||
import LayoutTag from './layout'
|
||||
import BlockTag from './block'
|
||||
import RawTag from './raw'
|
||||
import TablerowTag from './tablerow'
|
||||
import UnlessTag from './unless'
|
||||
import BreakTag from './break'
|
||||
import ContinueTag from './continue'
|
||||
import EchoTag from './echo'
|
||||
import LiquidTag from './liquid'
|
||||
import InlineCommentTag from './inline-comment'
|
||||
import type { TagClass } from '../template/tag'
|
||||
|
||||
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'
|
||||
|
||||
export default class extends Tag {
|
||||
private hash: Hash
|
||||
private tpls: Template[]
|
||||
private file?: ParsedFileName
|
||||
args: Hash
|
||||
templates: Template[]
|
||||
file?: ParsedFileName
|
||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(token, remainTokens, liquid)
|
||||
const tokenizer = new Tokenizer(token.args, this.liquid.options.operators)
|
||||
this.file = parseFilePath(tokenizer, this.liquid)
|
||||
this['currentFile'] = token.file
|
||||
this.hash = new Hash(tokenizer.remaining())
|
||||
this.tpls = this.liquid.parser.parseTokens(remainTokens)
|
||||
this.args = new Hash(tokenizer.remaining())
|
||||
this.templates = this.liquid.parser.parseTokens(remainTokens)
|
||||
}
|
||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
|
||||
const { liquid, hash, file } = this
|
||||
const { liquid, args, file } = this
|
||||
const { renderer } = liquid
|
||||
if (file === undefined) {
|
||||
ctx.setRegister('blockMode', BlockMode.OUTPUT)
|
||||
yield renderer.renderTemplates(this.tpls, ctx, emitter)
|
||||
yield renderer.renderTemplates(this.templates, ctx, emitter)
|
||||
return
|
||||
}
|
||||
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
|
||||
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')
|
||||
|
||||
// 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)
|
||||
|
||||
// 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)
|
||||
ctx.pop()
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
import { Template, Tokenizer, Emitter, Liquid, TopLevelToken, TagToken, Context, Tag } from '..'
|
||||
|
||||
export default class extends Tag {
|
||||
private tpls: Template[]
|
||||
templates: Template[]
|
||||
constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(token, remainTokens, liquid)
|
||||
const tokenizer = new Tokenizer(token.args, this.liquid.options.operators)
|
||||
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> {
|
||||
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'
|
||||
|
||||
export default class extends Tag {
|
||||
private variable: string
|
||||
private hash: Hash
|
||||
private templates: Template[]
|
||||
private collection: ValueToken
|
||||
variable: string
|
||||
args: Hash
|
||||
templates: Template[]
|
||||
collection: ValueToken
|
||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(tagToken, remainTokens, liquid)
|
||||
const tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operators)
|
||||
@@ -23,7 +23,7 @@ export default class extends Tag {
|
||||
|
||||
this.variable = variable.content
|
||||
this.collection = collectionToken
|
||||
this.hash = new Hash(tokenizer.remaining())
|
||||
this.args = new Hash(tokenizer.remaining())
|
||||
this.templates = []
|
||||
|
||||
let p
|
||||
@@ -40,12 +40,12 @@ export default class extends Tag {
|
||||
|
||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, unknown> {
|
||||
let collection = toEnumerable(yield evalToken(this.collection, ctx))
|
||||
const hash = (yield this.hash.render(ctx)) as Record<string, any>
|
||||
const offset = hash.offset || 0
|
||||
const limit = (hash.limit === undefined) ? collection.length : hash.limit
|
||||
const args = (yield this.args.render(ctx)) as Record<string, any>
|
||||
const offset = args.offset || 0
|
||||
const limit = (args.limit === undefined) ? collection.length : args.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 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 '..'
|
||||
|
||||
export default class extends Tag {
|
||||
private branches: { predicate: Value, test: (val: any, ctx: Context) => boolean, templates: Template[] }[] = []
|
||||
private elseTemplates: Template[] = []
|
||||
branches: { value: Value, test: (val: any, ctx: Context) => boolean, templates: Template[] }[] = []
|
||||
elseTemplates: Template[] = []
|
||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(tagToken, remainTokens, liquid)
|
||||
let p
|
||||
this.liquid.parser.parseStream(remainTokens)
|
||||
.on('start', () => this.branches.push({
|
||||
predicate: new Value(tagToken.args, this.liquid),
|
||||
value: new Value(tagToken.args, this.liquid),
|
||||
test: isFalsy,
|
||||
templates: (p = [])
|
||||
}))
|
||||
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
||||
predicate: new Value(token.args, this.liquid),
|
||||
value: new Value(token.args, this.liquid),
|
||||
test: isTruthy,
|
||||
templates: (p = [])
|
||||
}))
|
||||
@@ -27,9 +27,9 @@ export default class extends Tag {
|
||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
|
||||
const r = this.liquid.renderer
|
||||
|
||||
for (const { predicate, test, templates } of this.branches) {
|
||||
const value = yield predicate.value(ctx, ctx.opts.lenientIf)
|
||||
if (test(value, ctx)) {
|
||||
for (const { value, test, templates } of this.branches) {
|
||||
const v = yield value.value(ctx, ctx.opts.lenientIf)
|
||||
if (test(v, ctx)) {
|
||||
yield r.renderTemplates(templates, ctx, emitter)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Liquid } from '../liquid'
|
||||
import { Filter } from './filter'
|
||||
|
||||
export class Output extends TemplateImpl<OutputToken> implements Template {
|
||||
private value: Value
|
||||
value: Value
|
||||
public constructor (token: OutputToken, liquid: Liquid) {
|
||||
super(token)
|
||||
this.value = new Value(token.content, liquid)
|
||||
|
||||
Reference in New Issue
Block a user