agentsclimarketplace

Odoo xml conventions

Skill omas-odoo/odoo-superpowers/skills/odoo-xml-conventions

Use when writing, reviewing, or migrating any .xml file in an Odoo module — views, actions, menus, security records, data files, QWeb templates. Holds Odoo's naming, formatting, inheritance, and cross-version syntax conventions. Invoke before adding records to views/, security/, data/, or report/ directories.From its SKILL.md

Install
npx -y skills add omas-odoo/odoo-superpowers --skill odoo-xml-conventions

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

5.2 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it

Odoo XML Conventions

Write the backend XML an experienced reviewer wouldn't comment on — so the review is about the design, not the naming. These are stances to carry, not a checklist to run: the exact patterns — naming tables, attribute order, xpath and version syntax — live in references/, pulled only when you need the fact. When a task skips the planning pass (odoo-grill), these reflexes carry the design alone.

Scope is backend XML — view, action, menu, security, and data records. OWL/QWeb client templates under static/src are odoo-js's domain — the inheritance instinct rhymes (extend, don't replace) but the directives and file conventions differ.

The stances

An external id is a contract, not a label

The XML id outlives the code that writes it: once a customer DB stores account_move_view_form, every ref=, every inheriting module, every Studio customization, and every migration script points at that string — renaming it isn't a rename, it's a break. So spend the naming thought up front, module-prefixed and descriptive, so the next person finds the record by guessing its id. The canonical patterns aren't aesthetics; they're the shared vocabulary reviewers and tooling (web_studio, OCA) parse. Legacy non-conforming ids you can't rename without a migration stay as-is — but new ids you add still follow the convention; don't let the exception spread. (Exact patterns: references/xml-naming.md.)

Inherit a view — never redefine it

When you need a field on someone else's form, your default is an xpath into their view, not a fresh copy: a copy forks the UI and silently drops every other module's contributions the day core changes the original. Anchor the xpath on something stable — a named field, a named page — never a position index, which shifts the moment any module inserts above you. An extension keeps the original's id and earns the .inherit.<module> name suffix; a primary view is a genuinely new record and takes a new id with no suffix. Get the suffix wrong (underscores where dots belong, or missing entirely) and the override loads silently wrong. (xpath, primary-vs-extension, suffix mechanics: references/xml-inheritance.md, references/xml-naming.md.)

The view is the UI — don't rebuild it in Python

Odoo's view layer already renders labels, formats, conditional visibility, and grouping; reaching into Python to assemble HTML, hardcode a layout, or compute what a <filter> or an invisible= expression states declaratively is fighting the framework — it won't theme, translate, or survive an upgrade. An empty <search> is the same mistake in miniature: it overrides the freebie Odoo generates with something worse, so give it the obvious search field, the lifecycle filters, and a group-by. Add a view type only when the model earns it — each one is surface area someone else maintains. (search and view-type forms: references/xml-format.md.)

Declare data with the narrowest semantics it needs

noupdate is a promise about who owns a record after install: noupdate="1" says "the customer may edit this and my next module update must not stomp it" (config seed, parameters), plain records say "this is mine, re-asserted on every upgrade" (views, actions, security). Decide per-record intent, not per-file habit — wrap only the locked records in <data noupdate="1">, and if the whole file is locked put it on <odoo> directly rather than a redundant <data>. Keep one concept per file (views / menus / security / data each their own) so review and demo-data loading stay predictable. (noupdate and data-tag forms: references/xml-format.md.)

Match the target version's era — a mismatch fails silent

XML doesn't reject an attribute from the wrong Odoo era, it ignores it: a v16 attrs= on a v17 DB simply never hides the field, no error to catch it. So before writing gating or inheriting a core view, know which major you target and which tag/attribute it actually renders — <tree> vs <list>, attrs=/states= vs inline invisible=/readonly=. When inheriting, your xpath must match the tag the target version renders, not the one you remember. (Era-by-era syntax: references/version-changes.md; the JS side of a port: odoo-js.)

References (consult for the fact, don't memorize)

Need the exact...Read
id / name pattern for a view, action, menu, group, or rulereferences/xml-naming.md
attribute order, <menuitem>/<template>, <search>, noupdate/<data> formreferences/xml-format.md
xpath anchor, primary-vs-extension, position= valuesreferences/xml-inheritance.md
pre/post-v17 gating, <tree><list>, column_invisiblereferences/version-changes.md

At review time see also odoo-code-review; for where each XML file lives in the module, odoo-module-development.

What ships with it: 4 files

18.2 KB alongside SKILL.md

Gives 0 of the 12 instructions most docs writing skills give in ~1.2k tokens

Counted across 1,637 of the 3,044 authors here whose files we hold, read 2026-08-07

  • Announce the skill at startin 54 of 1637, across 26 files
  • Convert legacy doc files before editingin 45 of 1637, across 7 files
  • Predict questions readers might askin 42 of 1637, across 4 files
  • Generate clarifying questions for initial contextin 42 of 1637, across 3 files
  • Create document scaffold with placeholder textin 42 of 1637, across 3 files
  • Brainstorm content options for each sectionin 42 of 1637, across 3 files
  • Test the document with a fresh context-less instancein 42 of 1637, across 3 files
  • Include exact file paths in every taskin 42 of 1637, across 15 files
  • Ask interview questions one at a timein 42 of 1637, across 27 files
  • Apply surgical edits during refinementin 41 of 1637, across 2 files
  • Offer structured workflow or freeformin 40 of 1637, across 1 file
  • Ask for document meta-contextin 40 of 1637, across 2 files

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,645. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.