diff --git a/web/static/src/ts/core/qweb_vdom.ts b/web/static/src/ts/core/qweb_vdom.ts index 49b41a07..747c1575 100644 --- a/web/static/src/ts/core/qweb_vdom.ts +++ b/web/static/src/ts/core/qweb_vdom.ts @@ -425,7 +425,11 @@ export class QWeb { } if (name.startsWith("t-attf-")) { - const attName = name.slice(7); + let attName = name.slice(7); + if (!attName.match(/^[a-zA-Z]+$/)) { + // attribute contains 'non letters' => we want to quote it + attName = '"' + attName + '"'; + } const formattedExpr = value!.replace( /\{\{.*?\}\}/g, s => "${" + this._formatExpression(s.slice(2, -2)) + "}" diff --git a/web/static/tests/core/__snapshots__/qweb_vdom.test.ts.snap b/web/static/tests/core/__snapshots__/qweb_vdom.test.ts.snap index fe1e29c9..2632eda1 100644 --- a/web/static/tests/core/__snapshots__/qweb_vdom.test.ts.snap +++ b/web/static/tests/core/__snapshots__/qweb_vdom.test.ts.snap @@ -33,6 +33,17 @@ exports[`attributes dynamic attributes 1`] = ` }" `; +exports[`attributes dynamic formatted attributes with a dash 1`] = ` +"function anonymous(context,extra +) { + let h = this.h; + let _1 = \`Some text \${context['id']}\`; + let c2 = [], p2 = {key:2,attrs:{\\"aria-label\\": _1}}; + let vn2 = h('div', p2, c2); + return vn2; +}" +`; + exports[`attributes fixed variable 1`] = ` "function anonymous(context,extra ) { diff --git a/web/static/tests/core/qweb_vdom.test.ts b/web/static/tests/core/qweb_vdom.test.ts index cf3a0e7d..3435650e 100644 --- a/web/static/tests/core/qweb_vdom.test.ts +++ b/web/static/tests/core/qweb_vdom.test.ts @@ -316,6 +316,12 @@ describe("attributes", () => { expect(result).toBe(`
`); }); + test("dynamic formatted attributes with a dash", () => { + qweb.addTemplate("test", `
`); + const result = renderToString(qweb, "test", { id: 32 }); + expect(result).toBe(`
`); + }); + test("fixed variable", () => { qweb.addTemplate("test", `
`); const result = renderToString(qweb, "test", { value: "ok" });