diff --git a/base_view_inheritance_extension/README.rst b/base_view_inheritance_extension/README.rst
new file mode 100644
index 000000000..f5eaa8ba6
--- /dev/null
+++ b/base_view_inheritance_extension/README.rst
@@ -0,0 +1,83 @@
+.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg
+ :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
+ :alt: License: LGPL-3
+
+=========================
+Extended view inheritance
+=========================
+
+This module was written to make it simple to add custom operators for view inheritance.
+
+Usage
+=====
+
+.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
+ :alt: Try me on Runbot
+ :target: https://runbot.odoo-community.org/runbot/149/9.0
+
+Change a python dictionary (context for example)
+------------------------------------------------
+
+.. code-block:: xml
+
+
+ $new_value
+
+
+Note that views are subject to evaluation of xmlids anyways, so if you need to refer to some xmlid, say ``%(xmlid)s``.
+
+Move an element in the view
+---------------------------
+
+.. code-block:: xml
+
+
+
+This can also be used to wrap some element into another, create the target element first, then move the node youwant to wrap there.
+
+Known issues / Roadmap
+======================
+
+* add ``$value``
+* add ``$index``
+* add ``$value``
+* support ````
+* support an ``eval`` attribute for our new node types
+
+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 smashing it by providing a detailed and welcomed feedback.
+
+Credits
+=======
+
+Images
+------
+
+* Odoo Community Association: `Icon `_.
+
+Contributors
+------------
+
+* Holger Brunn
+
+Do not contact contributors directly about help with questions or problems concerning this addon, but use the `community mailing list `_ or the `appropriate specialized mailinglist `_ for help, and the bug tracker linked in `Bug Tracker`_ above for technical issues.
+
+Maintainer
+----------
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+This module is maintained by the OCA.
+
+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.
+
+To contribute to this module, please visit https://odoo-community.org.
diff --git a/base_view_inheritance_extension/__init__.py b/base_view_inheritance_extension/__init__.py
new file mode 100644
index 000000000..4431c72c4
--- /dev/null
+++ b/base_view_inheritance_extension/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# © 2016 Therp BV
+# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
+from . import models
diff --git a/base_view_inheritance_extension/__openerp__.py b/base_view_inheritance_extension/__openerp__.py
new file mode 100644
index 000000000..d4304a540
--- /dev/null
+++ b/base_view_inheritance_extension/__openerp__.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+# © 2016 Therp BV
+# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
+{
+ "name": "Extended view inheritance",
+ "version": "9.0.1.0.0",
+ "author": "Therp BV,Odoo Community Association (OCA)",
+ "license": "LGPL-3",
+ "category": "Hidden/Dependency",
+ "summary": "Adds more operators for view inheritance",
+ "depends": [
+ 'base',
+ ],
+ "demo": [
+ "demo/ir_ui_view.xml",
+ ],
+}
diff --git a/base_view_inheritance_extension/demo/ir_ui_view.xml b/base_view_inheritance_extension/demo/ir_ui_view.xml
new file mode 100644
index 000000000..648a19cb5
--- /dev/null
+++ b/base_view_inheritance_extension/demo/ir_ui_view.xml
@@ -0,0 +1,22 @@
+
+
+
+
+ res.partner
+
+
+
+ Partner form
+
+
+ 'The company name'
+ context.get('company_id', context.get('company'))
+
+
+
+
+
+
+
+
+
diff --git a/base_view_inheritance_extension/models/__init__.py b/base_view_inheritance_extension/models/__init__.py
new file mode 100644
index 000000000..588d249e2
--- /dev/null
+++ b/base_view_inheritance_extension/models/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# © 2016 Therp BV
+# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
+from . import ir_ui_view
diff --git a/base_view_inheritance_extension/models/ir_ui_view.py b/base_view_inheritance_extension/models/ir_ui_view.py
new file mode 100644
index 000000000..752220079
--- /dev/null
+++ b/base_view_inheritance_extension/models/ir_ui_view.py
@@ -0,0 +1,124 @@
+# -*- coding: utf-8 -*-
+# © 2016 Therp BV
+# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
+from lxml import etree
+from openerp import api, models, tools
+
+
+class UnquoteObject(str):
+ def __getattr__(self, name):
+ return UnquoteObject('%s.%s' % (self, name))
+
+ def __repr__(self):
+ return self
+
+ def __call__(self, *args, **kwargs):
+ return UnquoteObject(
+ '%s(%s)' % (
+ self,
+ ','.join(
+ [
+ UnquoteObject(
+ a if not isinstance(a, basestring)
+ else "'%s'" % a
+ )
+ for a in args
+ ] +
+ [
+ '%s=%s' % (UnquoteObject(k), v)
+ for (k, v) in kwargs.iteritems()
+ ]
+ )
+ )
+ )
+
+
+class UnquoteEvalObjectContext(tools.misc.UnquoteEvalContext):
+ def __missing__(self, key):
+ return UnquoteObject(key)
+
+
+class IrUiView(models.Model):
+ _inherit = 'ir.ui.view'
+
+ @api.model
+ def apply_inheritance_specs(self, source, specs_tree, inherit_id):
+ for specs, handled_by in self._iter_inheritance_specs(specs_tree):
+ source = handled_by(source, specs, inherit_id)
+ return source
+
+ @api.model
+ def _iter_inheritance_specs(self, spec):
+ if spec.tag == 'data':
+ for child in spec:
+ for node, handler in self._iter_inheritance_specs(child):
+ yield node, handler
+ return
+ if spec.get('position') == 'attributes':
+ for child in spec:
+ node = etree.Element(spec.tag, **spec.attrib)
+ node.insert(0, child)
+ yield node, self._get_inheritance_handler_attributes(
+ child
+ )
+ return
+ yield spec, self._get_inheritance_handler(spec)
+
+ @api.model
+ def _get_inheritance_handler(self, node):
+ handler = super(IrUiView, self).apply_inheritance_specs
+ if hasattr(
+ self, 'inheritance_handler_%s' % node.tag
+ ):
+ handler = getattr(
+ self,
+ 'inheritance_handler_%s' % node.tag
+ )
+ return handler
+
+ @api.model
+ def _get_inheritance_handler_attributes(self, node):
+ handler = super(IrUiView, self).apply_inheritance_specs
+ if hasattr(
+ self, 'inheritance_handler_attributes_%s' % node.get('operation')
+ ):
+ handler = getattr(
+ self,
+ 'inheritance_handler_attributes_%s' % node.get('operation')
+ )
+ return handler
+
+ @api.model
+ def inheritance_handler_attributes_python_dict(
+ self, source, specs, inherit_id
+ ):
+ """Implement
+ <$node position="attributes">
+
+ $keyvalue
+
+ $node>"""
+ node = self.locate_node(source, specs)
+ for attribute_node in specs:
+ python_dict = tools.safe_eval(
+ node.get(attribute_node.get('name')) or '{}',
+ UnquoteEvalObjectContext()
+ )
+ python_dict[attribute_node.get('key')] = UnquoteObject(
+ attribute_node.text
+ )
+ node.attrib[attribute_node.get('name')] = str(python_dict)
+ return source
+
+ @api.model
+ def inheritance_handler_xpath(self, source, specs, inherit_id):
+ if not specs.get('position') == 'move':
+ return super(IrUiView, self).apply_inheritance_specs(
+ source, specs, inherit_id
+ )
+ node = self.locate_node(source, specs)
+ target_node = self.locate_node(
+ source, etree.Element(specs.tag, expr=specs.get('target'))
+ )
+ target_node.append(node)
+ return source
diff --git a/base_view_inheritance_extension/static/description/icon.png b/base_view_inheritance_extension/static/description/icon.png
new file mode 100644
index 000000000..3a0328b51
Binary files /dev/null and b/base_view_inheritance_extension/static/description/icon.png differ
diff --git a/base_view_inheritance_extension/tests/__init__.py b/base_view_inheritance_extension/tests/__init__.py
new file mode 100644
index 000000000..f76aba46a
--- /dev/null
+++ b/base_view_inheritance_extension/tests/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# © 2016 Therp BV
+# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
+from . import test_base_view_inheritance_extension
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
new file mode 100644
index 000000000..2429b4f6f
--- /dev/null
+++ b/base_view_inheritance_extension/tests/test_base_view_inheritance_extension.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# © 2016 Therp BV
+# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
+from lxml import etree
+from openerp.tests.common import TransactionCase
+
+
+class TestBaseViewInheritanceExtension(TransactionCase):
+ def test_base_view_inheritance_extension(self):
+ view_id = self.env.ref('base.view_partner_form').id
+ fields_view_get = self.env['res.partner'].fields_view_get(
+ view_id=view_id
+ )
+ view = etree.fromstring(fields_view_get['arch'])
+ # verify normal attributes work
+ self.assertEqual(view.xpath('//form')[0].get('string'), 'Partner form')
+ # verify our extra context key worked
+ self.assertTrue(
+ 'default_name' in
+ view.xpath('//field[@name="parent_id"]')[0].get('context')
+ )
+ self.assertTrue(
+ "context.get('company_id', context.get('company'))" in
+ view.xpath('//field[@name="parent_id"]')[0].get('context')
+ )
+ # verify we moved the child_ids field
+ self.assertEqual(
+ view.xpath('//field[@name="child_ids"]')[0].getparent(),
+ view.xpath('//page[@name="my_new_page"]')[0]
+ )