Skip to content

Commit

Permalink
feat: use different Squirrelly delimiters
Browse files Browse the repository at this point in the history
By using now {{{ and }}} as delimiters, i.e. different
from Vue's <template> expression delimiters {{ and }},
less escaping will be needed.

See also
squirrellyjs/squirrelly-docs#18 (comment)
  • Loading branch information
lourot committed Sep 6, 2023
1 parent 85d05b8 commit c360bc1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 39 deletions.
16 changes: 12 additions & 4 deletions packages/core/src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,19 @@ export function transformAstAndGenerate(tree: ASTNode, meta: VikeMeta, options:
export function renderSquirrelly(template: string, meta: VikeMeta): string {
let output = "";
try {
output = render(template, {
import: {
meta,
output = render(
template,
{
import: {
meta,
},
},
{
// We use {{{ and }}} as Squirrelly delimiters so that {{ and }} remain untouched in Vue SFC files, in which
// they are used in Vue <template>s.
tags: ["{{{", "}}}"],
},
});
);
} catch (e) {
console.error("SquirrellyJS rendering error:", (e as Error).message);
throw e;
Expand Down
57 changes: 22 additions & 35 deletions packages/core/tests/parse.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,9 @@ test("squirrelly if telefunc", async () => {
<Sidebar>
<Logo />
<Link href="/">Welcome</Link>
{{ @if (it.import.meta.BATI_MODULES?.includes("rpc:telefunc")) }}
{{{ @if (it.import.meta.BATI_MODULES?.includes("rpc:telefunc")) }}}
<Link href="/todo">Todo</Link>
{{ /if }}
{{{ /if }}}
<Link href="/star-wars">Data Fetching</Link>
</Sidebar>
<Content><slot /></Content>
Expand Down Expand Up @@ -398,9 +398,9 @@ test("squirrelly if not telefunc", async () => {
<Sidebar>
<Logo />
<Link href="/">Welcome</Link>
{{ @if (it.import.meta.BATI_MODULES?.includes("rpc:telefunc")) }}
{{{ @if (it.import.meta.BATI_MODULES?.includes("rpc:telefunc")) }}}
<Link href="/todo">Todo</Link>
{{ /if }}
{{{ /if }}}
<Link href="/star-wars">Data Fetching</Link>
</Sidebar>
<Content><slot /></Content>
Expand Down Expand Up @@ -434,15 +434,15 @@ test("squirrelly if-else tailwind", async () => {
<div id="page-container">
<div
id="page-content"
{{ @if (it.import.meta.BATI_MODULES?.includes("uikit:tailwindcss")) }}
{{{ @if (it.import.meta.BATI_MODULES?.includes("uikit:tailwindcss")) }}}
class="p-5 pb-12 min-h-screen"
{{ #else }}
{{{ #else }}}
style="
padding: 20px;
padding-bottom: 50px;
min-height: 100vh;
"
{{ /if }}
{{{ /if }}}
>
<slot />
</div>
Expand Down Expand Up @@ -476,15 +476,15 @@ test("squirrelly if-else not tailwind", async () => {
<div id="page-container">
<div
id="page-content"
{{ @if (it.import.meta.BATI_MODULES?.includes("uikit:tailwindcss")) }}
{{{ @if (it.import.meta.BATI_MODULES?.includes("uikit:tailwindcss")) }}}
class="p-5 pb-12 min-h-screen"
{{ #else }}
{{{ #else }}}
style="
padding: 20px;
padding-bottom: 50px;
min-height: 100vh;
"
{{ /if }}
{{{ /if }}}
>
<slot />
</div>
Expand Down Expand Up @@ -516,7 +516,7 @@ test("squirrelly if-else not tailwind", async () => {
test("squirrelly comments", async () => {
const renderedOutput = renderSquirrelly(
`
{{! /* We are using the SquirrellyJS template syntax */ _}}
{{{! /* We are using the SquirrellyJS template syntax */ _}}}
<!-- Default <head> (can be overridden by pages) -->
Expand All @@ -537,20 +537,18 @@ test("squirrelly comments", async () => {
);
});

test("squirrelly escaping", async () => {
// `{{ state.count }}` is Vue SFC template syntax, so it should be escaped,
// otherwise SquirrellyJS will try to evaluate it and throw a ReferenceError
// because it doesn't know `state`.
test("squirrelly double brackets", async () => {
// `{{ state.count }}` is Vue SFC template syntax and we have configured SquirrellyJS to use three
// curly brackets as delimiter, so it should leave double brackets untouched.
const renderedOutput = renderSquirrelly(
`
<template>
<button
type="button"
@click="state.count++"
>
{{! /* This is the way to escape '{{' and have Squirrelly pass it on to Vue.
See https://squirrelly.js.org/docs/syntax/overview/ */ _}}
Counter {{ "{{" }} state.count }}
{{{! /* Double curly brackets are left untouched: */ _}}}
Counter {{ state.count }}
</button>
</template>`,
{},
Expand All @@ -570,21 +568,10 @@ test("squirrelly escaping", async () => {
);
});

test("squirrelly forgot escaping", async () => {
assert.throws(
() =>
renderSquirrelly(
`
<template>
<button
type="button"
@click="state.count++"
>
Counter {{ state.count }}
</button>
</template>`,
{},
),
ReferenceError,
);
test("squirrelly unknown reference", async () => {
assert.throws(() => renderSquirrelly("{{{ unknown }}}", {}), ReferenceError);
});

test("squirrelly syntax error", async () => {
assert.throws(() => renderSquirrelly("hello {{{", {}), Error);
});

0 comments on commit c360bc1

Please sign in to comment.