From a1d7e6c9872cfa4794c08d8f6eefbf855f48d705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Fri, 17 May 2019 16:14:54 +0200 Subject: [PATCH] [FIX] qweb: support #{} syntax in attribute string interpolation closes #113 --- doc/qweb.md | 22 +++++++++++++++++++--- src/qweb_core.ts | 10 ++++++---- tests/__snapshots__/qweb.test.ts.snap | 11 +++++++++++ tests/qweb.test.ts | 6 ++++++ 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/doc/qweb.md b/doc/qweb.md index dce6b7f2..ea58143e 100644 --- a/doc/qweb.md +++ b/doc/qweb.md @@ -12,7 +12,8 @@ - [`t-set` directive](#t-set-directive) - [`t-if` directive](#t-if-directive) - [Expression evaluation](#expression-evaluation) - - [`t-att` directive (dynamic attributes)](#t-att-directive-dynamic-attributes) + - [Dynamic attributes (`t-att` and `t-attf` directives)](#dynamic-attributes-t-att-and-t-attf-directives) + - [`t-attf` directive (dynamic attributes)](#t-att-directive-dynamic-attributes) - [`t-call` directive (sub templates)](#t-call-directive-sub-templates) - [JS/OWL Specific Extensions](#jsowl-specific-extensions) @@ -257,7 +258,7 @@ compile time.

ok

``` -### `t-att` directive (dynamic attributes) +### Dynamic attributes (`t-att` and `t-attf` directives) One can use the `t-att-` directive to add dynamic attributes. Its main use is to evaluate an expression (at rendering time) and bind an attribute to its result: @@ -265,7 +266,7 @@ evaluate an expression (at rendering time) and bind an attribute to its result: For example, if we have `id` set to 32 in the rendering context, ```xml -
+
``` If an expression evaluates to a falsy value, it will not be set at all: @@ -274,6 +275,21 @@ If an expression evaluates to a falsy value, it will not be set at all:
``` +There is another way to format a string attribute: the `t-attf-` directive. With +it, you get string interpolation: + +```xml +
+ +``` + +For historical reason, there is an alternate form of string interpolation: + +```xml +
+ +``` + ### `t-call` directive (sub templates) QWeb templates can be used for top level rendering, but they can also be used diff --git a/src/qweb_core.ts b/src/qweb_core.ts index 11d63fe4..a007a7ab 100644 --- a/src/qweb_core.ts +++ b/src/qweb_core.ts @@ -457,6 +457,9 @@ export class QWeb { props.push(`${key}: _${val}`); } } + function formatter(expr) { + return "${" + ctx.formatExpression(expr) + "}"; + } for (let i = 0; i < attributes.length; i++) { let name = attributes[i].name; @@ -515,10 +518,9 @@ export class QWeb { // attribute contains 'non letters' => we want to quote it attName = '"' + attName + '"'; } - const formattedExpr = value!.replace( - /\{\{.*?\}\}/g, - s => "${" + ctx.formatExpression(s.slice(2, -2)) + "}" - ); + const formattedExpr = value! + .replace(/\{\{.*?\}\}/g, s => formatter(s.slice(2, -2))) + .replace(/\#\{.*?\}/g, s => formatter(s.slice(2, -1))); const attID = ctx.generateID(); let staticVal = (node).getAttribute(attName); if (staticVal) { diff --git a/tests/__snapshots__/qweb.test.ts.snap b/tests/__snapshots__/qweb.test.ts.snap index 3bb77670..92355c51 100644 --- a/tests/__snapshots__/qweb.test.ts.snap +++ b/tests/__snapshots__/qweb.test.ts.snap @@ -93,6 +93,17 @@ exports[`attributes format expression 1`] = ` }" `; +exports[`attributes format expression, other format 1`] = ` +"function anonymous(context,extra +) { + var h = this.utils.h; + var _1 = \`\${context['value'] + 37}\`; + let c2 = [], p2 = {key:2,attrs:{foo: _1}}; + var vn2 = h('div', p2, c2); + return vn2; +}" +`; + exports[`attributes format literal 1`] = ` "function anonymous(context,extra ) { diff --git a/tests/qweb.test.ts b/tests/qweb.test.ts index 3b3808a3..54446d93 100644 --- a/tests/qweb.test.ts +++ b/tests/qweb.test.ts @@ -511,6 +511,12 @@ describe("attributes", () => { expect(result).toBe(`
`); }); + test("format expression, other format", () => { + qweb.addTemplate("test", `
`); + const result = renderToString(qweb, "test", { value: 5 }); + expect(result).toBe(`
`); + }); + test("format multiple", () => { qweb.addTemplate( "test",