Skip to content

Commit

Permalink
[FIX] base: render db manager w/ qweb and no db
Browse files Browse the repository at this point in the history
Due to odoo#82724 and 8ec7739,
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 odoo#81024
which introduces a limited helper `render()` method in ir_qweb so that
it can be used statically without a database.

Fixes odoo#82835

closes odoo#82841

X-original-commit: 3014e92
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Signed-off-by: Olivier Dony <odo@odoo.com>
  • Loading branch information
odony committed Jan 16, 2022
1 parent 48a60fe commit 1b8fa10
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
4 changes: 2 additions & 2 deletions addons/web/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down
40 changes: 40 additions & 0 deletions odoo/addons/base/models/ir_qweb.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 1b8fa10

Please sign in to comment.