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 () => {