diff --git a/base_view_inheritance_extension/README.rst b/base_view_inheritance_extension/README.rst index d8906b5d2b0..775fccb8ed9 100644 --- a/base_view_inheritance_extension/README.rst +++ b/base_view_inheritance_extension/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ========================= Extended view inheritance ========================= @@ -17,7 +13,7 @@ Extended view inheritance .. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png :target: https://odoo-community.org/page/development-status :alt: Mature -.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github @@ -76,10 +72,43 @@ conditional changes** $domain_to_add +**Wrap loose text in an element for further processing** + +.. code:: xml + + + + +which transforms + +.. code:: xml + + + + plain text 1 + + plain text2 + + + +to + +.. code:: xml + + + + plain text 1 + +
plain text2
+
+
+ +making those texts accessible for further operations + Known issues / Roadmap ====================== -- Support an ``eval`` attribute for our new node types. +- Support an ``eval`` attribute for our new node types. Bug Tracker =========== @@ -102,19 +131,19 @@ Authors Contributors ------------ -- Holger Brunn -- Ronald Portier -- `Tecnativa `__: +- Holger Brunn +- Ronald Portier +- `Tecnativa `__: - - Sergio Teruel - - Carlos Dauden + - Sergio Teruel + - Carlos Dauden -- `Trobz `__: +- `Trobz `__: - - Nhan Tran + - Nhan Tran -- Iván Todorovich -- Frederic Grall +- Iván Todorovich +- Frederic Grall Maintainers ----------- @@ -129,6 +158,14 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. +.. |maintainer-hbrunn| image:: https://github.com/hbrunn.png?size=40px + :target: https://github.com/hbrunn + :alt: hbrunn + +Current `maintainer `__: + +|maintainer-hbrunn| + This module is part of the `OCA/server-tools `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_view_inheritance_extension/__manifest__.py b/base_view_inheritance_extension/__manifest__.py index 7851b86825b..82f561db455 100644 --- a/base_view_inheritance_extension/__manifest__.py +++ b/base_view_inheritance_extension/__manifest__.py @@ -12,4 +12,5 @@ "website": "https://github.com/OCA/server-tools", "depends": ["base"], "demo": ["demo/ir_ui_view.xml"], + "maintainers": ["hbrunn"], } diff --git a/base_view_inheritance_extension/models/ir_ui_view.py b/base_view_inheritance_extension/models/ir_ui_view.py index b845791adc8..053110347a7 100644 --- a/base_view_inheritance_extension/models/ir_ui_view.py +++ b/base_view_inheritance_extension/models/ir_ui_view.py @@ -9,6 +9,7 @@ from lxml import etree from odoo import api, models +from odoo.exceptions import ValidationError from odoo.osv import expression @@ -83,6 +84,85 @@ def _get_inheritance_handler(self, node): handler = getattr(self, f"inheritance_handler_{node.tag}") return handler + @api.model + def inheritance_handler_wraptext(self, source, specs): + """Implement wraptext inheritance spec + + .. code-block:: xml + + + + Which transforms xml like + + .. code-block:: xml + + + + plain text + + + + + to + + .. code-block:: xml + + + + plain text + + + + + """ + if len(specs): + raise ValidationError(self.env._("wraptext elements cannot have children")) + + expression = specs.attrib.get("expr") + found = source.xpath(specs.attrib["expr"]) + if not found: + raise ValidationError( + self.env._("wraptext: nothing found for expression %r", expression) + ) + + found = found[0] + text_position = specs.attrib.get("position", "text") + if text_position not in ("text", "tail"): + raise ValidationError( + self.env._("wraptext: the only valid positions are 'text' or 'tail'") + ) + + wrapped = etree.Element(specs.attrib.get("element", "t")) + wrapped.text = getattr(found, text_position) + setattr(found, text_position, None) + + if self.env.context.get("edit_translations") and not wrapped.text: + # translation might have wrapped the text already in a element + # we wrap this element so that subsequent view manipulations find + # the wrapped element at the same position in the tree it would be at + # without translation + next_sibling = found.getnext() + + if ( + text_position == "text" + and len(found) + and found[0].attrib.get("data-oe-translation-state") + ): + wrapped.append(found[0]) + elif ( + text_position == "tail" + and next_sibling is not None + and next_sibling.attrib.get("data-oe-translation-state") + ): + wrapped.append(next_sibling) + + if text_position == "text": + found.insert(0, wrapped) + elif text_position == "tail": + found.addnext(wrapped) + + return source + @api.model def _get_inheritance_handler_attributes(self, node): handler = super().apply_inheritance_specs diff --git a/base_view_inheritance_extension/readme/CONTRIBUTORS.md b/base_view_inheritance_extension/readme/CONTRIBUTORS.md index af1f41160bd..8393673c0d7 100644 --- a/base_view_inheritance_extension/readme/CONTRIBUTORS.md +++ b/base_view_inheritance_extension/readme/CONTRIBUTORS.md @@ -1,4 +1,4 @@ -- Holger Brunn \<\> +- Holger Brunn \<\> - Ronald Portier \<\> - [Tecnativa](https://www.tecnativa.com): - Sergio Teruel diff --git a/base_view_inheritance_extension/readme/USAGE.md b/base_view_inheritance_extension/readme/USAGE.md index e4bda1aa927..eccdf027aec 100644 --- a/base_view_inheritance_extension/readme/USAGE.md +++ b/base_view_inheritance_extension/readme/USAGE.md @@ -30,3 +30,36 @@ conditional changes** $domain_to_add ``` + +**Wrap loose text in an element for further processing** + +``` xml + + +``` + +which transforms + +``` xml + + + plain text 1 + + plain text2 + + +``` + +to + +``` xml + + + plain text 1 + +
plain text2
+
+
+``` + +making those texts accessible for further operations diff --git a/base_view_inheritance_extension/static/description/index.html b/base_view_inheritance_extension/static/description/index.html index 4f59755ca4b..7d0e5d48f5d 100644 --- a/base_view_inheritance_extension/static/description/index.html +++ b/base_view_inheritance_extension/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Extended view inheritance -
+
+

Extended view inheritance

- - -Odoo Community Association - -
-

Extended view inheritance

-

Mature License: LGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

+

Mature License: LGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

This module was written to make it simple to add custom operators for view inheritance.

Table of contents

@@ -392,7 +387,7 @@

Extended view inheritance

-

Usage

+

Usage

Change a python dictionary (context for example)

 <field position="attributes">
@@ -419,15 +414,41 @@ 

Usage

$domain_to_add </attribute>
+

Wrap loose text in an element for further processing

+
+<wraptext expr="//some/node" position="text" element="span" />
+<wraptext expr="//some/node/other_node" position="tail" element="div" />
+
+

which transforms

+
+<some>
+    <node>
+        plain text 1
+        <other_node />
+        plain text2
+    </node>
+</some>
+
+

to

+
+<some>
+    <node>
+        <span>plain text 1</span>
+        <other_node />
+        <div>plain text2</div>
+    </node>
+</some>
+
+

making those texts accessible for further operations

-

Known issues / Roadmap

+

Known issues / Roadmap

  • Support an eval attribute for our new node types.
-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -435,17 +456,17 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Therp BV
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -469,11 +490,12 @@

Maintainers

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

+

Current maintainer:

+

hbrunn

This module is part of the OCA/server-tools project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

-
diff --git a/base_view_inheritance_extension/tests/test_base_view_inheritance_extension.py b/base_view_inheritance_extension/tests/test_base_view_inheritance_extension.py index eeaf22c2a73..158b41f2ba2 100644 --- a/base_view_inheritance_extension/tests/test_base_view_inheritance_extension.py +++ b/base_view_inheritance_extension/tests/test_base_view_inheritance_extension.py @@ -5,6 +5,7 @@ from lxml import etree +from odoo.exceptions import ValidationError from odoo.tests.common import TransactionCase @@ -199,3 +200,47 @@ def test_update_source_not_a_dict(self): ) with self.assertRaisesRegex(TypeError, "Attribute `domain` is not a dict"): self.env["ir.ui.view"].apply_inheritance_specs(source, specs) + + def test_wraptext(self): + """Test textwrap transformations""" + base_view = self.env["ir.ui.view"].create( + { + "type": "qweb", + "arch": "" + "plain text 1plain text2", + } + ) + inherited_view = self.env["ir.ui.view"].create( + { + "type": "qweb", + "inherit_id": base_view.id, + "arch": "" + '' + '' + "", + } + ) + self.assertEqual( + base_view.with_context(load_all_views=True).get_combined_arch(), + "plain text 1" + "
plain text2
", + ) + translatable_arch = base_view.with_context( + load_all_views=True, edit_translations=True + )._get_combined_arch() + self.assertTrue( + translatable_arch.xpath("//some/node/span/span[@data-oe-translation-state]") + ) + self.assertTrue( + translatable_arch.xpath("//some/node/div/span[@data-oe-translation-state]") + ) + + with self.assertRaisesRegex(ValidationError, "children"): + inherited_view.write({"arch": ""}) + with self.assertRaisesRegex(ValidationError, "found"): + inherited_view.write({"arch": ''}) + with self.assertRaisesRegex(ValidationError, "positions"): + inherited_view.write( + {"arch": ''} + )