From 025c40f0f2f13efa62193c61d2fa56943917ac3c Mon Sep 17 00:00:00 2001 From: Yang Jun Date: Thu, 15 May 2025 01:47:57 +0800 Subject: [PATCH] fix: block.super with strictVariables, #806 (#807) --- README.md | 1 + src/drop/block-drop.ts | 9 ++++++--- src/tags/block.ts | 6 +++++- test/integration/tags/layout.spec.ts | 20 ++++++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4cb7bf44d..9f07da9f9 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ For more details, refer to the [Setup Guide][setup]. ## Who's Using LiquidJS? - [Eleventy](https://www.11ty.dev/): Eleventy, a simpler static site generator. +- [Github Docs](https://github.com/github/docs): The open-source repo for docs.github.com. - [Opensense](https://www.opensense.com/): The smarter way to send email. - [Directus](https://docs.directus.io/): an instant REST+GraphQL API and intuitive no-code data collaboration app for any SQL database. - [Semgrep](https://github.com/returntocorp/semgrep): Lightweight static analysis for many languages. diff --git a/src/drop/block-drop.ts b/src/drop/block-drop.ts index 0e994aa92..2ff1aa297 100644 --- a/src/drop/block-drop.ts +++ b/src/drop/block-drop.ts @@ -1,9 +1,10 @@ +import { Emitter, SimpleEmitter } from '../emitters' import { Drop } from './drop' export class BlockDrop extends Drop { constructor ( // the block render from layout template - private superBlockRender: () => Iterable = () => '' + private superBlockRender: (emitter: Emitter) => IterableIterator | string = () => '' ) { super() } @@ -11,7 +12,9 @@ export class BlockDrop extends Drop { * Provide parent access in child block by * {{ block.super }} */ - public super () { - return this.superBlockRender() + public * super (): IterableIterator { + const emitter = new SimpleEmitter() + yield this.superBlockRender(emitter) + return emitter.buffer } } diff --git a/src/tags/block.ts b/src/tags/block.ts index 022c25100..6ae147ac0 100644 --- a/src/tags/block.ts +++ b/src/tags/block.ts @@ -39,7 +39,11 @@ export default class extends Tag { ctx.pop() } return renderChild - ? (superBlock: BlockDrop, emitter: Emitter) => renderChild(new BlockDrop(() => renderCurrent(superBlock, emitter)), emitter) + ? (superBlock: BlockDrop, emitter: Emitter) => renderChild( + new BlockDrop( + (emitter: Emitter) => renderCurrent(superBlock, emitter) + ), + emitter) : renderCurrent } diff --git a/test/integration/tags/layout.spec.ts b/test/integration/tags/layout.spec.ts index 7a944c588..5f0e4beb8 100644 --- a/test/integration/tags/layout.spec.ts +++ b/test/integration/tags/layout.spec.ts @@ -101,6 +101,26 @@ describe('tags/layout', function () { const output = '' return expect(html).toBe(output) }) + it('should pass block.super as a string', async function () { + mock({ + '/parent.html': '{% block css %}{% endblock %}' + }) + const src = '{% layout "parent.html" %}' + + '{%block css%}{{block.super}}{%endblock%}' + const html = await liquid.parseAndRender(src) + const output = '' + return expect(html).toBe(output) + }) + it('should support block.super while strictVariables', async function () { + mock({ + '/parent.html': '{% block css %}{% endblock %}' + }) + const src = '{% layout "parent.html" %}' + + '{%block css%}{{block.super}}{%endblock%}' + const html = await liquid.parseAndRender(src, undefined, { strictVariables: true }) + const output = '' + return expect(html).toBe(output) + }) it('should render block.super to empty if no parent exists', async function () { mock({ '/parent.html': '{% block css %}{{block.super}}{% endblock %}'