Steff
Steff

Reputation: 41

Odoo 15: Complex view inheritance

I would like to create a new "E-Commerce" tab in the product form and move the fields added by the website module into it.

Creating the new tab :

<record id="product_ecom_tab" model="ir.ui.view">
  <field name="name">Product Ecom Tab Form</field>
  <field name="model">product.template</field>
  <field name="inherit_id" ref="product.product_template_form_view"/>
  <field name="arch" type="xml">
    <xpath expr="//page[@name='sales']" position="after">
      <page name="product_ecom" string="E-Commerce">
      </page>
    </xpath>
  </field>
</record>

So then I though I could simply change the view used by the website :

<record id="product_ecom_details_move" model="ir.ui.view">
  <field name="name">Product Ecom Details Move</field>
  <field name="model">product.template</field>
  <field name="inherit_id" ref="website_sale.product_template_form_view"/>
  <field name="arch" type="xml">
    <xpath expr="//xpath[2]" position="attributes">
      <attribute name="expr">//page[@name='product_ecom']</attribute>
      <attribute name="position">inside</attribute>
    </xpath>
  </field>
</record>

Two problem here :

  1. Cannot select xpath tag and modify its expr attribute
  2. In this view, I cannot refer to page added in another inherited view

Any clean solution ?

Upvotes: 0

Views: 741

Answers (1)

Travis Waelbroeck
Travis Waelbroeck

Reputation: 2135

I don't fully understand what you're trying to do from your question, but I think the details below should help regardless. Both of these issues seem to come from confusion about how we might expect view inheritance to work vs how Odoo designed it to work.

  1. Cannot select xpath tag and modify its expr attribute

See Odoo Views documentation about Inheritance Specs for reference.

When you are inheriting with xpath, you will never use xpath in the actual expr of your xpath node.

<!-- This doesn't work -->
<xpath expr="//xpath[2]" position="attributes">

The above doesn't work, because Odoo is going to try to apply your view inheritance on top of a "rendered" view, which will already have resolved that view's xpath.

Instead, you need to write your xpath to a portion of the "rendered" view.

View you want to inherit

<!-- The xpath or any other node with a `position` will not be rendered in the final view -->
<xpath expr="//page[@name='sales']" position="after">
    <!-- The contents of the xpath or any other `position` node **will* be rendered -->
    <page name="product_ecom" string="E-Commerce">
    </page>
</xpath>

Your view, which inherits from the above view

<!-- Hook your `expr` onto a rendered element -->
<xpath expr="//page[@name='product_ecom']" position="inside">
    <!-- For inside/before/after, your content will be rendered -->
    <page name="my_new_page" string="My New Page">
    </page>
</xpath>
<xpath expr="//page[@name='product_ecom']" position="attributes">
    <!-- For attributes, your content will change an existing rendered element -->
    <attribute name="string">New page label</attribute>
</xpath>

  1. In this view, I cannot refer to page added in another inherited view

It depends on the view inheritance of whatever you're trying to refer to. For example, consider the following structure:

product.product_template_form_view
├── other_module.website_sale.product_template_form_view
│   └── yet_another_module.product_template_form_view
└── website_sale.product_template_form_view

If I am inheriting product.product_template_form_view, but I want to refer to an element from yet_another_module.product_template_form_view, then Odoo may do a couple of "not great" things, such as:

  • It can render my view before the yet_another_module view, which would result in an error.
  • If the yet_another_module app is uninstalled and my app doesn't depend on it, then we result in another potential error.

If I want to refer to something from the yet_another_module app, then I need to (1) depend on that module in my module's __manifest__.py and (2) write a view that specifically inherits from the yet_another_module view.

Upvotes: 2

Related Questions