diff --git a/src/render/emitter.ts b/src/render/emitter.ts new file mode 100644 index 000000000..8e199dd28 --- /dev/null +++ b/src/render/emitter.ts @@ -0,0 +1,7 @@ +export class Emitter { + public html: string = ''; + + public write (html: string) { + this.html += html + } +} diff --git a/src/render/render.ts b/src/render/render.ts index 2f06971b4..d49244e01 100644 --- a/src/render/render.ts +++ b/src/render/render.ts @@ -2,23 +2,24 @@ import { RenderError } from '../util/error' import assert from '../util/assert' import Context from '../context/context' import ITemplate from '../template/itemplate' +import { Emitter } from './emitter' export default class Render { public async renderTemplates (templates: ITemplate[], ctx: Context) { assert(ctx, 'unable to evalTemplates: context undefined') - let html = '' + const emitter = new Emitter() for (const tpl of templates) { try { - html += await tpl.render(ctx) + emitter.write(await tpl.render(ctx, emitter)) } catch (e) { if (e.name === 'RenderBreakError') { - e.resolvedHTML = html + e.resolvedHTML = emitter.html throw e } throw e.name === 'RenderError' ? e : new RenderError(e, tpl) } } - return html + return emitter.html } } diff --git a/src/template/itemplate.ts b/src/template/itemplate.ts index e0f9580ef..401afecfd 100644 --- a/src/template/itemplate.ts +++ b/src/template/itemplate.ts @@ -1,7 +1,8 @@ import Context from '../context/context' import Token from '../parser/token' +import { Emitter } from '../render/emitter' export default interface ITemplate { token: Token; - render(ctx: Context): Promise; + render(ctx: Context, emitter: Emitter): Promise; } diff --git a/test/integration/builtin/tags/for.ts b/test/integration/builtin/tags/for.ts index 96ffca041..0eba9f08c 100644 --- a/test/integration/builtin/tags/for.ts +++ b/test/integration/builtin/tags/for.ts @@ -113,13 +113,23 @@ describe('tags/for', function () { const html = await liquid.parseAndRender(src, ctx) return expect(html).to.equal('12345') }) - it('should support for with break', async function () { - const src = '{% for i in (one..5) %}' + - '{% if i == 4 %}{% break %}{% endif %}' + - '{{ i }}' + - '{% endfor %}' - const html = await liquid.parseAndRender(src, ctx) - return expect(html).to.equal('123') + describe('break', function () { + it('should support break', async function () { + const src = '{% for i in (one..5) %}' + + '{% if i == 4 %}{% break %}{% endif %}' + + '{{ i }}' + + '{% endfor %}' + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('123') + }) + it('should output contents before break', async function () { + const src = '{% for i in (1..5) %}' + + '{% if i == 4 %}breaking{% break %}{% endif %}' + + '{{ i }}' + + '{% endfor %}' + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('123breaking') + }) }) describe('limit', function () {