From 13af401bc2c4286cabc87b4c409d478350e5d6d3 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Wed, 28 Dec 2016 22:00:29 +0100 Subject: [PATCH] [FIX] QWeb: xml namespaces and t-call Before this commit, when a t-call attribute triggered the compilation of a template, the compilation of this template was not aware of the nsmap of the parent, resulting in redundant xml namespaces declaration. With this commit, we pass the current nsmap through the `options` dict. --- odoo/addons/base/ir/ir_qweb/qweb.py | 71 +++++++++++++++++++++++------ odoo/addons/base/tests/test_qweb.py | 3 ++ 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/odoo/addons/base/ir/ir_qweb/qweb.py b/odoo/addons/base/ir/ir_qweb/qweb.py index 67488586538..c7615248c29 100644 --- a/odoo/addons/base/ir/ir_qweb/qweb.py +++ b/odoo/addons/base/ir/ir_qweb/qweb.py @@ -269,7 +269,8 @@ class QWeb(object): _options['ast_calls'] = [] _options['root'] = element.getroottree() _options['last_path_node'] = None - _options['nsmap'] = {} + if not options.get('nsmap'): + _options['nsmap'] = {} # generate ast @@ -1296,6 +1297,7 @@ class QWeb(object): tmpl = el.attrib.pop('t-call') _values = self._make_name('values_copy') call_options = el.attrib.pop('t-call-options', None) + nsmap = options.get('nsmap') _values = self._make_name('values_copy') @@ -1362,9 +1364,10 @@ class QWeb(object): ) ) - if call_options: + if nsmap or call_options: + # copy the original dict of options to pass to the callee name_options = self._make_name('options') - content.extend([ + content.append( # options_ = options.copy() ast.Assign( targets=[ast.Name(id=name_options, ctx=ast.Store())], @@ -1376,18 +1379,56 @@ class QWeb(object): ), args=[], keywords=[], starargs=None, kwargs=None ) - ), - # options_.update(template options) - ast.Expr(ast.Call( - func=ast.Attribute( - value=ast.Name(id=name_options, ctx=ast.Load()), - attr='update', - ctx=ast.Load() - ), - args=[self._compile_expr(call_options)], - keywords=[], starargs=None, kwargs=None - )) - ]) + ) + ) + + if call_options: + # update this dict with the content of `t-call-options` + content.extend([ + # options_.update(template options) + ast.Expr(ast.Call( + func=ast.Attribute( + value=ast.Name(id=name_options, ctx=ast.Load()), + attr='update', + ctx=ast.Load() + ), + args=[self._compile_expr(call_options)], + keywords=[], starargs=None, kwargs=None + )) + ]) + + if nsmap: + # update this dict with the current nsmap so that the callee know + # if he outputting the xmlns attributes is relevenat or not + + # make the nsmap an ast dict + keys = [] + values = [] + for key, value in options['nsmap'].items(): + if isinstance(key, basestring): + keys.append(ast.Str(s=key)) + elif key is None: + keys.append(ast.Name(id='None', ctx=ast.Load())) + values.append(ast.Str(s=value)) + + # {'nsmap': {None: 'xmlns def'}} + nsmap_ast_dict = ast.Dict( + keys=[ast.Str(s='nsmap')], + values=[ast.Dict(keys=keys, values=values)] + ) + + # options_.update(nsmap_ast_dict) + content.append( + ast.Expr(ast.Call( + func=ast.Attribute( + value=ast.Name(id=name_options, ctx=ast.Load()), + attr='update', + ctx=ast.Load() + ), + args=[nsmap_ast_dict], + keywords=[], starargs=None, kwargs=None + )) + ) else: name_options = 'options' diff --git a/odoo/addons/base/tests/test_qweb.py b/odoo/addons/base/tests/test_qweb.py index 284cc104840..67cb98ffcb7 100644 --- a/odoo/addons/base/tests/test_qweb.py +++ b/odoo/addons/base/tests/test_qweb.py @@ -373,6 +373,9 @@ class TestQWebNS(TransactionCase): self.assertEquals(len(cac_lines), 2) self.assertEquals(result.count('Appel'), 2) + # check that the t-call dit not output again the xmlns declaration + self.assertEquals(result.count('xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"'), 1) + def test_render_static_xml_with_extension(self): """ Test the extension of a view by an xpath expression on a ns prefixed element. """