[IMP] web: allow lazy-loading asset bundles' templates
Previously, lazy-loading xml templates was only possible by fetching the xml file directly, this meant that it was impossible to lazy-load an entire bundle's templates with a single request. Additionally, requesting the xml files directly meant that no inheritance was applied, causing the need for a separate inheritance system using t-jquery on the client-side. This commit alters the /web/webclient/qweb route so that it now takes a bundle id, meaning that it is now possible to lazy-load the xml from arbitrary bundles. task-2497943 closes odoo/odoo#70084 Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit is contained in:
@@ -549,13 +549,13 @@ class HomeStaticTemplateHelpers(object):
|
||||
|
||||
return etree.tostring(root, encoding='utf-8') if root is not None else b'', checksum.hexdigest()[:64]
|
||||
|
||||
def _get_asset_paths(self):
|
||||
def _get_asset_paths(self, bundle):
|
||||
"""Proxy for ir_asset._get_asset_paths
|
||||
Useful to make 'self' testable.
|
||||
"""
|
||||
return request.env['ir.asset']._get_asset_paths(addons=self.addons, bundle='web.assets_qweb', xml=True)
|
||||
return request.env['ir.asset']._get_asset_paths(addons=self.addons, bundle=bundle, xml=True)
|
||||
|
||||
def _get_qweb_templates(self):
|
||||
def _get_qweb_templates(self, bundle):
|
||||
"""One and only entry point that gets and evaluates static qweb templates
|
||||
|
||||
:rtype: (str, str)
|
||||
@@ -563,7 +563,7 @@ class HomeStaticTemplateHelpers(object):
|
||||
xml_paths = defaultdict(list)
|
||||
|
||||
# group paths by module, keeping them in order
|
||||
for path, addon, _ in self._get_asset_paths():
|
||||
for path, addon, _ in self._get_asset_paths(bundle):
|
||||
addon_paths = xml_paths[addon]
|
||||
if path not in addon_paths:
|
||||
addon_paths.append(path)
|
||||
@@ -572,12 +572,12 @@ class HomeStaticTemplateHelpers(object):
|
||||
return content, checksum
|
||||
|
||||
@classmethod
|
||||
def get_qweb_templates_checksum(cls, addons=None, db=None, debug=False):
|
||||
return cls(addons, db, checksum_only=True, debug=debug)._get_qweb_templates()[1]
|
||||
def get_qweb_templates_checksum(cls, addons=None, db=None, debug=False, bundle=None):
|
||||
return cls(addons, db, checksum_only=True, debug=debug)._get_qweb_templates(bundle)[1]
|
||||
|
||||
@classmethod
|
||||
def get_qweb_templates(cls, addons=None, db=None, debug=False):
|
||||
return cls(addons, db, debug=debug)._get_qweb_templates()[0]
|
||||
def get_qweb_templates(cls, addons=None, db=None, debug=False, bundle=None):
|
||||
return cls(addons, db, debug=debug)._get_qweb_templates(bundle)[0]
|
||||
|
||||
|
||||
class GroupsTreeNode:
|
||||
@@ -934,12 +934,12 @@ class WebClient(http.Controller):
|
||||
])
|
||||
|
||||
@http.route('/web/webclient/qweb/<string:unique>', type='http', auth="none", cors="*")
|
||||
def qweb(self, unique, mods=None, db=None):
|
||||
def qweb(self, unique, mods=None, db=None, bundle=None):
|
||||
|
||||
if not request.db and mods is None:
|
||||
mods = odoo.conf.server_wide_modules or []
|
||||
|
||||
content = HomeStaticTemplateHelpers.get_qweb_templates(mods, db, debug=request.session.debug)
|
||||
content = HomeStaticTemplateHelpers.get_qweb_templates(mods, db, debug=request.session.debug, bundle=bundle)
|
||||
|
||||
return request.make_response(content, [
|
||||
('Content-Type', 'text/xml'),
|
||||
|
||||
@@ -51,7 +51,7 @@ class Http(models.AbstractModel):
|
||||
mods = odoo.conf.server_wide_modules or []
|
||||
if request.db:
|
||||
mods = list(request.registry._init_modules) + mods
|
||||
qweb_checksum = HomeStaticTemplateHelpers.get_qweb_templates_checksum(debug=request.session.debug)
|
||||
qweb_checksum = HomeStaticTemplateHelpers.get_qweb_templates_checksum(debug=request.session.debug, bundle="web.assets_qweb")
|
||||
lang = user_context.get("lang")
|
||||
translation_hash = request.env['ir.translation'].get_web_translations_hash(mods, lang)
|
||||
menu_json_utf8 = json.dumps(request.env['ir.ui.menu'].load_menus(request.session.debug), default=ustr, sort_keys=True).encode()
|
||||
|
||||
@@ -225,7 +225,7 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
|
||||
var lock = this.qweb_mutex.exec(function () {
|
||||
var cacheId = self.cache_hashes && self.cache_hashes.qweb;
|
||||
var route = '/web/webclient/qweb/' + (cacheId ? cacheId : Date.now());
|
||||
return $.get(route).then(function (doc) {
|
||||
return $.get(route, { bundle: 'web.assets_qweb' }).then(function (doc) {
|
||||
if (!doc) { return; }
|
||||
const owlTemplates = [];
|
||||
for (let child of doc.querySelectorAll("templates > [owl]")) {
|
||||
|
||||
@@ -1293,7 +1293,9 @@ python implementation.
|
||||
Now, let us explain how the templates are loaded. Whenever the web client
|
||||
starts, a rpc is made to the */web/webclient/qweb* route. The server will then
|
||||
return a list of all templates defined in data files for each installed modules.
|
||||
The correct files are listed in the *qweb* entry in each module manifest.
|
||||
The correct files are listed in the *web.assets_qweb* entry in each module
|
||||
manifest. It is also possible to lazy-load another bundle's templates by calling
|
||||
this same route and giving it the corresponding "bundle" query parameter.
|
||||
|
||||
The web client will wait for that list of template to be loaded, before starting
|
||||
its first widget.
|
||||
|
||||
Reference in New Issue
Block a user