diff --git a/doc/qweb.md b/doc/qweb.md index b9f5650a..ac08b5a0 100644 --- a/doc/qweb.md +++ b/doc/qweb.md @@ -129,6 +129,15 @@ It's API is quite simple: const str = qweb.renderToString("someTemplate", somecontext); ``` +- **`registerTemplate(name, template)`**: static function to register an global + QWeb template. This is useful for commonly used components accross the + application, and for making a template available to an application without + having a reference to the actual QWeb instance. + + ```js + QWeb.registerTemplate('mytemplate', `
some template`); + ``` + - **`register(name, Component)`**: static function to register an OWL Component to QWeb's global registry. Globally registered Components can be used in templates (see the `t-component` directive). This is useful for commonly used diff --git a/src/qweb/qweb.ts b/src/qweb/qweb.ts index 3da9f961..b61f075d 100644 --- a/src/qweb/qweb.ts +++ b/src/qweb/qweb.ts @@ -129,7 +129,7 @@ function parseXML(xml: string): Document { // QWeb rendering engine //------------------------------------------------------------------------------ export class QWeb extends EventBus { - templates: { [name: string]: Template } = {}; + templates: { [name: string]: Template }; static utils = UTILS; static components = Object.create(null); @@ -141,6 +141,8 @@ export class QWeb extends EventBus { }; static DIRECTIVES: Directive[] = []; + static TEMPLATES: { [name: string]: Template } = {}; + h = h; // dev mode enables better error messages or more costly validations static dev: boolean = false; @@ -160,6 +162,7 @@ export class QWeb extends EventBus { constructor(data?: string) { super(); + this.templates = Object.create(QWeb.TEMPLATES); if (data) { this.addTemplates(data); } @@ -184,6 +187,20 @@ export class QWeb extends EventBus { QWeb.components[name] = Component; } + /** + * Register globally a template. All QWeb instances will obtain their + * templates from their own template map, and then, from the global static + * TEMPLATES property. + */ + static registerTemplate(name: string, template: string) { + if (QWeb.TEMPLATES[name]) { + throw new Error(`Template '${name}' has already been registered`); + } + const qweb = new QWeb(); + qweb.addTemplate(name, template); + QWeb.TEMPLATES[name] = qweb.templates[name]; + } + /** * Add a template to the internal template map. Note that it is not * immediately compiled. diff --git a/tests/qweb/qweb.test.ts b/tests/qweb/qweb.test.ts index 7bcd8e62..b21fa4ae 100644 --- a/tests/qweb/qweb.test.ts +++ b/tests/qweb/qweb.test.ts @@ -11,6 +11,7 @@ import { normalize, renderToDOM, renderToString, trim, nextTick } from "../helpe let qweb: QWeb; beforeEach(() => { + QWeb.TEMPLATES = {}; qweb = new QWeb(); }); @@ -1278,3 +1279,22 @@ describe("update on event bus", () => { expect(fn).toBeCalledTimes(1); }); }); + +describe("global template registration", () => { + test("can register template globally", () => { + expect.assertions(5); + let qweb = new QWeb(); + try { + qweb.render("mytemplate"); + } catch (e) { + expect(e.message).toMatch("Template mytemplate does not exist"); + } + expect(qweb.templates.mytemplate).toBeUndefined(); + + QWeb.registerTemplate("mytemplate", "
global
"); + expect(qweb.templates.mytemplate).toBeDefined(); + const vnode = qweb.render("mytemplate"); + expect(vnode.sel).toBe("div"); + expect((vnode as any).children[0].text).toBe("global"); + }); +}); diff --git a/tests/router/RouteComponent.test.ts b/tests/router/RouteComponent.test.ts index 06526a58..97b7ef5f 100644 --- a/tests/router/RouteComponent.test.ts +++ b/tests/router/RouteComponent.test.ts @@ -53,7 +53,6 @@ describe("RouteComponent", () => { await nextTick(); expect(fixture.innerHTML).toBe("
Users
"); expect(env.qweb.templates[ROUTE_COMPONENT_TEMPLATE_NAME].fn.toString()).toMatchSnapshot(); - }); test("can render parameterized route", async () => {