mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 12:20:40 -07:00
feat: implement forloop.name as found in ruby shopify/liquid
This commit is contained in:
@@ -58,7 +58,7 @@ export default {
|
|||||||
return reversed(collection)
|
return reversed(collection)
|
||||||
}, collection)
|
}, collection)
|
||||||
|
|
||||||
const scope = { forloop: new ForloopDrop(collection.length) }
|
const scope = { forloop: new ForloopDrop(collection.length, this.collection.getText(), this.variable) }
|
||||||
ctx.push(scope)
|
ctx.push(scope)
|
||||||
for (const item of collection) {
|
for (const item of collection) {
|
||||||
scope[this.variable] = item
|
scope[this.variable] = item
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export default {
|
|||||||
const { value, alias } = this['for']
|
const { value, alias } = this['for']
|
||||||
let collection = evalToken(value, ctx)
|
let collection = evalToken(value, ctx)
|
||||||
collection = toEnumerable(collection)
|
collection = toEnumerable(collection)
|
||||||
scope['forloop'] = new ForloopDrop(collection.length)
|
scope['forloop'] = new ForloopDrop(collection.length, value.getText(), alias)
|
||||||
for (const item of collection) {
|
for (const item of collection) {
|
||||||
scope[alias] = item
|
scope[alias] = item
|
||||||
const templates = yield liquid._parsePartialFile(filepath, childCtx.sync)
|
const templates = yield liquid._parsePartialFile(filepath, childCtx.sync)
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ export default {
|
|||||||
parse: function (tagToken: TagToken, remainTokens: TopLevelToken[]) {
|
parse: function (tagToken: TagToken, remainTokens: TopLevelToken[]) {
|
||||||
const tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operatorsTrie)
|
const tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operatorsTrie)
|
||||||
|
|
||||||
this.variable = tokenizer.readIdentifier()
|
const variable = tokenizer.readIdentifier()
|
||||||
tokenizer.skipBlank()
|
tokenizer.skipBlank()
|
||||||
|
|
||||||
const tmp = tokenizer.readIdentifier()
|
const tmp = tokenizer.readIdentifier()
|
||||||
assert(tmp && tmp.content === 'in', () => `illegal tag: ${tagToken.getText()}`)
|
assert(tmp && tmp.content === 'in', () => `illegal tag: ${tagToken.getText()}`)
|
||||||
|
|
||||||
|
this.variable = variable.content
|
||||||
this.collection = tokenizer.readValue()
|
this.collection = tokenizer.readValue()
|
||||||
this.hash = new Hash(tokenizer.remaining())
|
this.hash = new Hash(tokenizer.remaining())
|
||||||
this.templates = []
|
this.templates = []
|
||||||
@@ -39,12 +40,12 @@ export default {
|
|||||||
const cols = hash.cols || collection.length
|
const cols = hash.cols || collection.length
|
||||||
|
|
||||||
const r = this.liquid.renderer
|
const r = this.liquid.renderer
|
||||||
const tablerowloop = new TablerowloopDrop(collection.length, cols)
|
const tablerowloop = new TablerowloopDrop(collection.length, cols, this.collection.getText(), this.variable)
|
||||||
const scope = { tablerowloop }
|
const scope = { tablerowloop }
|
||||||
ctx.push(scope)
|
ctx.push(scope)
|
||||||
|
|
||||||
for (let idx = 0; idx < collection.length; idx++, tablerowloop.next()) {
|
for (let idx = 0; idx < collection.length; idx++, tablerowloop.next()) {
|
||||||
scope[this.variable.content] = collection[idx]
|
scope[this.variable] = collection[idx]
|
||||||
if (tablerowloop.col0() === 0) {
|
if (tablerowloop.col0() === 0) {
|
||||||
if (tablerowloop.row() !== 1) emitter.write('</tr>')
|
if (tablerowloop.row() !== 1) emitter.write('</tr>')
|
||||||
emitter.write(`<tr class="row${tablerowloop.row()}">`)
|
emitter.write(`<tr class="row${tablerowloop.row()}">`)
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import { Drop } from './drop'
|
|||||||
|
|
||||||
export class ForloopDrop extends Drop {
|
export class ForloopDrop extends Drop {
|
||||||
protected i = 0
|
protected i = 0
|
||||||
|
public name: string
|
||||||
public length: number
|
public length: number
|
||||||
public constructor (length: number) {
|
public constructor (length: number, collection: string, variable: string) {
|
||||||
super()
|
super()
|
||||||
this.length = length
|
this.length = length
|
||||||
|
this.name = `${variable}-${collection}`
|
||||||
}
|
}
|
||||||
public next () {
|
public next () {
|
||||||
this.i++
|
this.i++
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { ForloopDrop } from './forloop-drop'
|
|||||||
|
|
||||||
export class TablerowloopDrop extends ForloopDrop {
|
export class TablerowloopDrop extends ForloopDrop {
|
||||||
private cols: number
|
private cols: number
|
||||||
public constructor (length: number, cols: number) {
|
public constructor (length: number, cols: number, collection: string, variable: string) {
|
||||||
super(length)
|
super(length, collection, variable)
|
||||||
this.length = length
|
this.length = length
|
||||||
this.cols = cols
|
this.cols = cols
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,22 @@ describe('tags/for', function () {
|
|||||||
it('should output forloop', async function () {
|
it('should output forloop', async function () {
|
||||||
const src = '{%for i in (1..1)%}{{forloop}}{%endfor%}'
|
const src = '{%for i in (1..1)%}{{forloop}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('{"i":0,"length":1}')
|
return expect(html).to.equal('{"i":0,"length":1,"name":"i-(1..1)"}')
|
||||||
|
})
|
||||||
|
it('should output forloop collection name', async function () {
|
||||||
|
const src = '{%for c in alpha%}{{forloop.name}}-{{c}}{%endfor%}'
|
||||||
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
|
return expect(html).to.equal('c-alpha-ac-alpha-bc-alpha-c')
|
||||||
|
})
|
||||||
|
it('should output forloop property accessor name', async function () {
|
||||||
|
const src = '{%for c in obj.foo%}{{forloop.name}}-{{c}}{%endfor%}'
|
||||||
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
|
return expect(html).to.equal('c-obj.foo-bar')
|
||||||
|
})
|
||||||
|
it('should output forloop quoted name', async function () {
|
||||||
|
const src = '{%for str in "string"%}{{forloop.name}}-{{str}}{%endfor%}'
|
||||||
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
|
return expect(html).to.equal('str-"string"-string')
|
||||||
})
|
})
|
||||||
describe('illegal', function () {
|
describe('illegal', function () {
|
||||||
it('should reject when for not closed', function () {
|
it('should reject when for not closed', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user