From 1b8fa102e98372cf1fd61db61792c7e20703aa87 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Sun, 16 Jan 2022 20:04:27 +0000 Subject: [PATCH] [FIX] base: render db manager w/ qweb and no db Due to #82724 and 8ec7739dd72fa0976697f7738b225dbb9efa7c97, the qweb renderer can't be used directly, however there is no way to use the proper ir.qweb one without a database. This is necessary for the /web/database/ routes (db manager) which work without a database, and require qweb rendering since the abandon of jinja rendering in v15. This patch builds on the preparation work of the qweb/ir_qweb merge in #81024 which introduces a limited helper `render()` method in ir_qweb so that it can be used statically without a database. Fixes #82835 closes odoo/odoo#82841 X-original-commit: 3014e922b48696fb9aba4b477ebe1878dd01bb69 Signed-off-by: Martin Trigaux (mat) Signed-off-by: Olivier Dony --- addons/web/controllers/main.py | 4 +-- odoo/addons/base/models/ir_qweb.py | 40 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 8a27b7d73d9fc..eb2de297d866b 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -31,7 +31,7 @@ import odoo import odoo.modules.registry from odoo.api import call_kw -from odoo.addons.base.models.qweb import QWeb +from odoo.addons.base.models.ir_qweb import render as qweb_render from odoo.modules import get_resource_path, module, get_manifest from odoo.tools import html_escape, pycompat, ustr, apply_inheritance_specs, lazy_property, float_repr, osutil from odoo.tools.mimetypes import guess_mimetype @@ -1082,7 +1082,7 @@ def _render_template(self, **d): def load(template_name, options): return (html.fragment_fromstring(templates[template_name]), template_name) - return QWeb()._render(html.document_fromstring(template), d, load=load) + return qweb_render(html.document_fromstring(template), d, load=load) @http.route('/web/database/selector', type='http', auth="none") def selector(self, **kw): diff --git a/odoo/addons/base/models/ir_qweb.py b/odoo/addons/base/models/ir_qweb.py index d0ce06cfda28f..72da524573ff6 100644 --- a/odoo/addons/base/models/ir_qweb.py +++ b/odoo/addons/base/models/ir_qweb.py @@ -355,3 +355,43 @@ def _compile_expr(self, expr, raise_on_missing=False): assert_valid_codeobj(_SAFE_QWEB_OPCODES, compile(namespace_expr, '<>', 'eval'), expr) return namespace_expr + + +def render(template_name, values, load, **options): + """ Rendering of a qweb template without database and outside the registry. + (Widget, field, or asset rendering is not implemented.) + :param (string|int) template_name: template identifier + :param dict values: template values to be used for rendering + :param def load: function like `load(template_name, options)` which + returns an etree from the given template name (from initial rendering + or template `t-call`). + :param options: used to compile the template (the dict available for the + rendering is frozen) + :returns: bytes marked as markup-safe (decode to :class:`markupsafe.Markup` + instead of `str`) + :rtype: MarkupSafe + """ + class MockPool: + db_name = None + _Registry__cache = {} + + class MockIrQWeb(IrQWeb): + pool = MockPool() + + def _get_field(self, *args): + raise NotImplementedError("Fields are not allowed in this rendering mode. Please use \"env['ir.qweb']._render\" method") + + def _get_widget(self, *args): + raise NotImplementedError("Widgets are not allowed in this rendering mode. Please use \"env['ir.qweb']._render\" method") + + def _get_asset_nodes(self, *args): + raise NotImplementedError("Assets are not allowed in this rendering mode. Please use \"env['ir.qweb']._render\" method") + + class MockEnv(dict): + def __init__(self): + super().__init__() + self.context = {} + + renderer = object.__new__(MockIrQWeb) + renderer.env = MockEnv() + return renderer._render(template_name, values, load=load, **options)