[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) <mat@odoo.com>
Signed-off-by: Olivier Dony <odo@odoo.com>
This commit is contained in:
Olivier Dony
2022-01-16 20:39:47 +00:00
parent 48a60fe268
commit 1b8fa102e9
2 changed files with 42 additions and 2 deletions
+2 -2
View File
@@ -31,7 +31,7 @@ from werkzeug.urls import url_encode, url_parse, iri_to_uri
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 @@ class Database(http.Controller):
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):
+40
View File
@@ -355,3 +355,43 @@ class IrQWeb(models.AbstractModel, QWeb):
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)