Skip to content

Commit

Permalink
fix: address harttle#404 to allow argument reassignment
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksandrHovhannisyan committed Oct 10, 2021
1 parent a525f45 commit ee830f9
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/builtin/tags/assign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default {
this.value = tokenizer.remaining()
},
render: function * (ctx: Context) {
ctx.bottom()[this.key] = yield this.liquid._evalValue(this.value, ctx)
const firstPageLevelScope = ctx.getFirstPageLevelScope()
firstPageLevelScope[this.key] = yield this.liquid._evalValue(this.value, ctx)
}
} as TagImplOptions
2 changes: 1 addition & 1 deletion src/builtin/tags/include.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default {
const scope = yield hash.render(ctx)
if (withVar) scope[filepath] = evalToken(withVar, ctx)
const templates = yield liquid._parsePartialFile(filepath, ctx.sync, this['currentFile'])
ctx.push(scope)
ctx.push({ ...scope, isPageLevel: true })
yield renderer.renderTemplates(templates, ctx, emitter)
ctx.pop()
ctx.restoreRegister(saved)
Expand Down
2 changes: 1 addition & 1 deletion src/builtin/tags/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default {
const { value, alias } = this['with']
scope[alias || filepath] = evalToken(value, ctx)
}
childCtx.push(scope)
childCtx.push({ ...scope, isPageLevel: true })

if (this['for']) {
const { value, alias } = this['for']
Expand Down
5 changes: 5 additions & 0 deletions src/context/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export class Context {
public bottom () {
return this.scopes[0]
}
/** Returns the first scope that's considered to be a page-level scope, if one exists. Otherwise, defaults to `bottom`. */
public getFirstPageLevelScope () {
const firstPageLevelScope = this.scopes.find((scope: Scope) => scope.isPageLevel)
return firstPageLevelScope || this.bottom()
}
private findScope (key: string) {
for (let i = this.scopes.length - 1; i >= 0; i--) {
const candidate = this.scopes[i]
Expand Down
6 changes: 5 additions & 1 deletion src/context/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ export interface PlainObject {
toLiquid?: () => any;
}

export type Scope = PlainObject | Drop
export type Scope = (PlainObject | Drop) & {
/** Whether this is a page-level scope (e.g., corresponding to include/render/layout).
* Transient scopes (like those created by a for loop) are not considered to be page-level scopes. */
isPageLevel?: boolean;
}
5 changes: 5 additions & 0 deletions test/integration/builtin/tags/assign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ describe('tags/assign', function () {
const html = await liquid.parseAndRender(src)
return expect(html).to.equal('-6')
})
it('should allow reassignment', async function () {
const src = '{% assign var = 1 %}{% assign var = 2 %}{{ var }}'
const html = await liquid.parseAndRender(src)
return expect(html).to.equal('2')
})
describe('scope', function () {
it('should read from parent scope', async function () {
const src = '{%for a in (1..2)%}{{num}}{%endfor%}'
Expand Down
10 changes: 10 additions & 0 deletions test/integration/builtin/tags/include.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,16 @@ describe('tags/include', function () {
const html = await staticLiquid.renderFile('parent.html')
return expect(html).to.equal('Xchild with redY')
})

it('should allow argument reassignment', async function () {
mock({
'/parent.html': '{% include child.html, color: "red" %}',
'/child.html': '{% assign color = "green" %}{{ color }}'
})
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
const html = await staticLiquid.renderFile('parent.html')
return expect(html).to.equal('green')
})
})
describe('sync support', function () {
it('should support quoted string', function () {
Expand Down

0 comments on commit ee830f9

Please sign in to comment.