Skip to content

Commit ee830f9

Browse files
fix: address harttle#404 to allow argument reassignment
1 parent a525f45 commit ee830f9

File tree

7 files changed

+29
-4
lines changed

7 files changed

+29
-4
lines changed

src/builtin/tags/assign.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default {
1010
this.value = tokenizer.remaining()
1111
},
1212
render: function * (ctx: Context) {
13-
ctx.bottom()[this.key] = yield this.liquid._evalValue(this.value, ctx)
13+
const firstPageLevelScope = ctx.getFirstPageLevelScope()
14+
firstPageLevelScope[this.key] = yield this.liquid._evalValue(this.value, ctx)
1415
}
1516
} as TagImplOptions

src/builtin/tags/include.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default {
3434
const scope = yield hash.render(ctx)
3535
if (withVar) scope[filepath] = evalToken(withVar, ctx)
3636
const templates = yield liquid._parsePartialFile(filepath, ctx.sync, this['currentFile'])
37-
ctx.push(scope)
37+
ctx.push({ ...scope, isPageLevel: true })
3838
yield renderer.renderTemplates(templates, ctx, emitter)
3939
ctx.pop()
4040
ctx.restoreRegister(saved)

src/builtin/tags/render.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export default {
5656
const { value, alias } = this['with']
5757
scope[alias || filepath] = evalToken(value, ctx)
5858
}
59-
childCtx.push(scope)
59+
childCtx.push({ ...scope, isPageLevel: true })
6060

6161
if (this['for']) {
6262
const { value, alias } = this['for']

src/context/context.ts

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ export class Context {
5757
public bottom () {
5858
return this.scopes[0]
5959
}
60+
/** Returns the first scope that's considered to be a page-level scope, if one exists. Otherwise, defaults to `bottom`. */
61+
public getFirstPageLevelScope () {
62+
const firstPageLevelScope = this.scopes.find((scope: Scope) => scope.isPageLevel)
63+
return firstPageLevelScope || this.bottom()
64+
}
6065
private findScope (key: string) {
6166
for (let i = this.scopes.length - 1; i >= 0; i--) {
6267
const candidate = this.scopes[i]

src/context/scope.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@ export interface PlainObject {
55
toLiquid?: () => any;
66
}
77

8-
export type Scope = PlainObject | Drop
8+
export type Scope = (PlainObject | Drop) & {
9+
/** Whether this is a page-level scope (e.g., corresponding to include/render/layout).
10+
* Transient scopes (like those created by a for loop) are not considered to be page-level scopes. */
11+
isPageLevel?: boolean;
12+
}

test/integration/builtin/tags/assign.ts

+5
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ describe('tags/assign', function () {
6969
const html = await liquid.parseAndRender(src)
7070
return expect(html).to.equal('-6')
7171
})
72+
it('should allow reassignment', async function () {
73+
const src = '{% assign var = 1 %}{% assign var = 2 %}{{ var }}'
74+
const html = await liquid.parseAndRender(src)
75+
return expect(html).to.equal('2')
76+
})
7277
describe('scope', function () {
7378
it('should read from parent scope', async function () {
7479
const src = '{%for a in (1..2)%}{{num}}{%endfor%}'

test/integration/builtin/tags/include.ts

+10
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,16 @@ describe('tags/include', function () {
194194
const html = await staticLiquid.renderFile('parent.html')
195195
return expect(html).to.equal('Xchild with redY')
196196
})
197+
198+
it('should allow argument reassignment', async function () {
199+
mock({
200+
'/parent.html': '{% include child.html, color: "red" %}',
201+
'/child.html': '{% assign color = "green" %}{{ color }}'
202+
})
203+
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
204+
const html = await staticLiquid.renderFile('parent.html')
205+
return expect(html).to.equal('green')
206+
})
197207
})
198208
describe('sync support', function () {
199209
it('should support quoted string', function () {

0 commit comments

Comments
 (0)