From 96ab29c9873ee3d0f603068c6bc0c2d4056a3081 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Mon, 28 Oct 2019 13:58:16 +0000 Subject: [PATCH] [IMP] web: template inheritance respects XPATH specs At the conception of this feature it has been intentionally thought that the behavior for static templates should resemble what is done for ir.ui.view While keeping the general previous behavior (and this is important) A little bit of context for ir.ui.view They are defined as XML's, but end up as python objects Their meta-data (id, name, inheritance specs...) are thus present in their XML definition, but end up as part of python objects members Hence, the final, business, usable arch is free of those meta-data and is left only with business-relevant dom nodes The static inheritance feature was backed with those ideas but inherently encountered the issue that, for them, the meta-data also end up in the business dom, since they are at no point considered as plain objects. Decision has been made, back then, to exclude the root node that holds the metadata, to be at all targeted by any XPATH This decision is now challenged as the specs of XPATH should be respected This commit consequently introduces the root node as any other It can be replaced, and will be targeted by `expr="."` or `expr="//NODE_TAG"` The few attributes that are necessary to define them are kept across inheritance cycles though. --- addons/web/controllers/main.py | 5 +-- addons/web/tests/test_serving_base.py | 45 +++++++++++++-------------- odoo/tools/template_inheritance.py | 3 ++ 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 24451c90e89..0ae52465604 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -509,15 +509,12 @@ class HomeStaticTemplateHelpers(object): # After several performance tests, we found out that deepcopy is the most efficient # solution in this case (compared with copy, xpath with '.' and stringifying). parent_tree = copy.deepcopy(self.template_dict[parent_addon][parent_name]) - parent_tag = parent_tree.tag - # replace temporarily the parent tag so it is never the target of the inheritance - parent_tree.tag = 't' + xpaths = list(template_tree) if self.debug and inherit_mode == self.EXTENSION_MODE: for xpath in xpaths: xpath.insert(0, etree.Comment(" Modified by %s from %s " % (template_name, addon))) inherited_template = apply_inheritance_specs(parent_tree, xpaths) - inherited_template.tag = parent_tag if inherit_mode == self.PRIMARY_MODE: # New template_tree: A' = B(A) inherited_template.set(self.NAME_TEMPLATE_DIRECTIVE, template_name) diff --git a/addons/web/tests/test_serving_base.py b/addons/web/tests/test_serving_base.py index 31be8bfa89e..87c01d748dc 100644 --- a/addons/web/tests/test_serving_base.py +++ b/addons/web/tests/test_serving_base.py @@ -397,7 +397,7 @@ class TestStaticInheritance(BaseCase):
- +
Sick XPath
@@ -408,7 +408,7 @@ class TestStaticInheritance(BaseCase):
- +
Mental XPath
@@ -476,9 +476,9 @@ class TestStaticInheritance(BaseCase): contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True) expected = b""" -
+
And I grew strong - +
""" @@ -510,11 +510,12 @@ class TestStaticInheritance(BaseCase): contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True) expected = b""" -
- And I grew strong +
+ + And I grew strong

And I learned how to get along

And so you're back - +
""" @@ -550,11 +551,11 @@ class TestStaticInheritance(BaseCase): contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True) expected = b""" -
+
And I grew strong

And I learned how to get along

- +
And so you're back
""" @@ -563,7 +564,7 @@ class TestStaticInheritance(BaseCase): def test_replace_root_node_tag(self): """ - Root node is not targeted by //NODE_TAG in xpath + Root node IS targeted by //NODE_TAG in xpath """ self.modules = [ ('module_1_file_1', None, 'module_1'), @@ -589,11 +590,10 @@ class TestStaticInheritance(BaseCase): contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True) expected = b""" -
-
At first I was afraid
+
-
Form replacer
- + Form replacer +
""" @@ -601,7 +601,7 @@ class TestStaticInheritance(BaseCase): def test_replace_root_node_tag_in_primary(self): """ - Root node is not targeted by //NODE_TAG in xpath + Root node IS targeted by //NODE_TAG in xpath """ self.maxDiff = None self.modules = [ @@ -630,10 +630,9 @@ class TestStaticInheritance(BaseCase):
At first I was afraid
Inner Form
-
-
At first I was afraid
-
Form replacer
-
+
+ Form replacer +
""" @@ -671,10 +670,10 @@ class TestStaticInheritance(BaseCase):
At first I was afraid
-
+
And I grew strong

And I learned how to get along

- +
""" @@ -708,11 +707,11 @@ class TestStaticInheritance(BaseCase): contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=False) expected = b""" -
+
And I grew strong

And I learned how to get along

And so you're back - +
""" diff --git a/odoo/tools/template_inheritance.py b/odoo/tools/template_inheritance.py index e025cd32712..77f738f2e2a 100644 --- a/odoo/tools/template_inheritance.py +++ b/odoo/tools/template_inheritance.py @@ -138,6 +138,9 @@ def apply_inheritance_specs(source, specs_tree, inherit_branding=False, pre_loca else: comment = content source = copy.deepcopy(spec_content) + for attr in ('t-name', 't-inherit'): + if node.get(attr): + source.set(attr, node.get(attr)) if comment is not None: text = source.text source.text = None