Skip to main content
iVentureTeam

resume_one2many

The Resume block on an Odoo employee form, with its timeline dots, date ranges and grouped experience types, is resume_one2many. It is a heavily customized one2many renderer with a hardcoded grouping and one genuine rendering bug that Odoo 20 fixes.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 26, 2026Updated August 26, 20266 min read
Technical nameresume_one2many
Field typesone2many
Viewsform
Modulehr_skills
Used in core2 occurrences across 1 module: both employee form variants in hr_skills
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0
No-code setupNo. Applied in XML with a custom inline list arch
Alternativesskills_one2many, one2many, internal_resume_lines

What the Resume timeline widget does

Open any employee in a database with the Skills Management app and the left side of the form shows Resume: entries like Experience, Education and Internal Certifications, each with a timeline dot, a bold date range and a description. That block is one field, resume_line_ids, rendered by resume_one2many.

The widget subclasses the skills family's skills_one2many and swaps in its own list renderer. The renderer inherits from the shared skills list renderer but replaces the row template wholesale: instead of columns it draws a two-cell row, a timeline cell with the colored dot, and a content cell with dates, title, an optional course link and the HTML description.

Dates get special treatment. A line with no end date prints Current; a line flagged as a course drops the range's second half and prints the duration in hours instead. All of it reads record data by literal field names: date_start, date_end, is_course, duration, external_url, name, description.

What this means for your team

The resume block turns the employee form into a living CV. HR teams use it to keep experience, education and certifications in one structured place, and because lines are typed and dated, the same data feeds skills reporting and internal mobility searches rather than sitting in an attached PDF.

The grouped Add buttons are a small workflow win: adding an Education line from the Education group header lands in a wizard with the type preset, one less dropdown for every entry. The e-learning integration goes further: completed internal courses append themselves as resume lines automatically, with the course link attached, so the CV grows without anyone typing.

For implementations, the message is that the resume is structured data with real reporting behind it. Companies migrating from documents to this block usually pair it with the skills matrix for a complete internal talent picture.

Supported options in Odoo 19

The widget declares nothing of its own; it spreads the skills_one2many descriptor, which itself relies on the generic x2many machinery. The crud gates below are read from the options dict at runtime rather than declared, exactly as on the parent, verified in the Odoo 19.0 source.

OptionTypeWhat it does
createboolean or domainInherited x2many crud gate for adding resume lines; also honored by the per-group Add buttons and the empty-state Create Resume Lines button. Runtime-read from options, never declared in supportedOptions.(since Odoo 17.0)
deleteboolean or domainInherited x2many crud gate for removing lines; controls the trash action column the renderer keeps from the base list.(since Odoo 17.0)
linkboolean or domainInherited x2many gate; relevant on many2many usage only, falls back to create when absent. The core resume field is a one2many, where it is moot.(since Odoo 17.0)
unlinkboolean or domainInherited x2many gate for detaching rather than deleting on many2many usage.(since Odoo 17.0)
writeboolean or domainInherited x2many gate; when false the sub-list renders readonly. The readonly gating in the generic component is itself 19-new.(since Odoo 17.0)

The real configuration lives in the view arch, not in options. The inline <list> inside the field decides which fields the renderer can read. Omit is_course or duration there and course lines silently render like plain lines; omit description and descriptions vanish. Core ships the full list for a reason.

Working examples

How core applies it (employee form)

<field mode="list" nolabel="1" name="resume_line_ids" widget="resume_one2many"
       context="{'default_employee_id': employee_id}">
    <list>
        <field name="line_type_id"/>
        <field name="name"/>
        <!-- date_start, date_end, description, is_course, duration, ... -->
    </list>
</field>

Core's own comment above this block explains the contract: the widget renders a custom list, and adding fields to the inline arch is what makes them accessible to it.

Reusing it on another one2many

<field mode="list" name="x_history_ids" widget="resume_one2many">
    <list>...same field names...</list>
</field>

Possible, but only if the target model mirrors the hr.resume.line field names, the renderer reads line_type_id, date_start and friends by literal name.

The one-ref link bug and the hardcoded grouping

Two implementation details separate this widget from a styled list, and one of them is a bug.

The single-ref link bug. Since Odoo 18 the renderer forces every link inside a resume description to open in a new tab, a sensible hardening for user-pasted HTML. But the template puts the same t-ref on every row's description paragraph, and Owl's useRef binds a single element, so the mounted and patched hooks only ever process one row's links. Descriptions in other rows keep their original targets. The Odoo 20 development branch migrates to Owl's new Resource ref-collection API and loops linkRef.items(), which processes every row and quietly fixes the bug.

Grouping without group_by. The renderer's groupBy getter returns line_type_id unconditionally. There is no view-level control; the resume is always grouped by type, and the group header's Add button injects default_line_type_id so new lines land in the right section.

The ecosystem extends the row template. hr_skills_slides inherits the record row to prefer course_url over external_url for the link icon, which is how completed e-learning courses link back to the course. In 19 the survey-based extension from earlier versions is gone, and a new sibling appeared: internal_resume_lines, a separate view widget rendered above the field that fetches company-side timeline entries through an ORM call rather than from the one2many.

Registration history. Odoo 16 registered the bare component class, so descriptor-level features did not exist; 17 introduced the spread descriptor; 18 added the link retargeting; 19 only tweaked a wizard title. The Odoo 20 branch's Resource migration is the first behavioral change since.

Version compatibility

VersionStatusNotes
Odoo 20.0VerifiedNot released. Resource ref migration fixes the link retargeting bug; see below.
Odoo 19.0VerifiedVerified against the shipped source; adds the internal_resume_lines sibling widget.
Odoo 18.0VerifiedAdds the new-tab link forcing on descriptions, with the single-ref limitation.
Odoo 17.0VerifiedDescriptor registration introduced; options machinery works from here.
Odoo 16.0Partial / changedClass-only registration; renders, but descriptor-level option handling does not exist.

Upgrade note. The widget exists since 16, but 16's class-only registration means x2many option gates were not extracted there; treat 16 views as display-only compatibility. From 17 on, views carry over unchanged.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026, and the development branch can still change.

The visible change is the Owl Resource migration: the renderer replaces its single useRef with a Resource collection and iterates items() when forcing description links to target a new tab. That turns the current one-row behavior into all-rows behavior, fixing the 18/19 quirk described above. The row templates, hardcoded grouping and field-name contract are unchanged, and the registration is untouched. We re-verify against the shipped release.

Common problems and fixes

SymptomCause and fix
Course duration or link icon does not appearis_course, duration or external_url is missing from the inline list arch, so the renderer cannot read it. Add the fields to the inline <list> inside the widget field, as the core form does.
Links in some resume descriptions open in the same tabThe 18/19 renderer's single ref only retargets one row's description links. Known source limitation, fixed by the Odoo 20 Resource migration; harden descriptions manually if it matters.
The resume ignores my group_by or column setupThe renderer hardcodes grouping by line_type_id and replaces the row template entirely. Use a standard one2many widget if you need configurable columns or grouping.
Nothing renders where the resume should beWith zero lines and edit rights, the table hides behind the Create Resume Lines button; without the inline list arch the renderer has no fields. Check for the empty-state button, and ensure the field carries mode="list" with an inline arch.
New lines land without an employee or typeThe context defaults are missing; core passes default_employee_id and the group buttons add default_line_type_id. Keep the context="{'default_employee_id': employee_id}" from the core arch, with employee_id loaded invisibly.

Resume timeline widget vs the alternatives

WidgetBest forKey difference
resume_one2manyThe typed, dated resume timeline on employee formsFully custom timeline renderer with hardcoded type grouping and course-aware rows
skills_one2manyThe skills matrix next to the resume on the same formSame wizard machinery but renders leveled skill groups instead of a timeline
one2manyGeneric editable sub-lists with configurable columnsStandard list rendering, view-controlled grouping and full option surface
internal_resume_linesThe company-side timeline block above the resume in 19A view widget fetching lines via ORM call, not bound to the one2many field

Within HR, this widget is the resume-specific sibling of skills_one2many; both share the wizard machinery and renderer base. For generic editable sub-lists, stay with the standard one2many, whose columns, options and editability are all configurable.

Frequently asked questions

What renders the Resume section on the Odoo employee form?+
The resume_one2many widget from the hr_skills module, applied to resume_line_ids. It draws a timeline grouped by resume line type with date ranges, titles, descriptions and course details.
Why must the fields be listed inside the widget's inline list arch?+
The custom renderer reads record data by literal field names, and only fields present in the inline <list> are loaded. Core's own XML comment documents this: adding fields there makes them accessible to the widget.
How do completed eLearning courses end up in the resume?+
hr_skills_slides appends a resume line when an internal course is completed and extends the row template so the link icon points at the course via course_url, taking priority over external_url.
Can I change how the resume is grouped?+
Not from XML; the renderer's groupBy getter hardcodes line_type_id. Different grouping means a custom renderer subclass or the standard one2many widget.
What does Current mean in a resume date range?+
A line with a start date and no end date prints Current instead of a second date, marking an ongoing position or study. Course lines never show a range end; they show the duration in hours.
Is the resume_one2many widget the same in Odoo 20?+
Behavior is unchanged on the development branch except one fix: the new-tab forcing of description links moves to Owl's Resource API and finally applies to every row instead of just one.

Employee data that works as hard as your team?

We implement Odoo HR with structured resumes, skills matrices and e-learning feeding one talent picture, including the custom timeline renderers and reporting layers on top, for Odoo 16 through 19.

Build my HR workspace

How this page was produced

This page was verified by reading resume_one2many.js and its templates in the Odoo 16.0 through 19.0 hr_skills sources, the hr_skills_slides template extension, the new internal_resume_one2many.js sibling, and the core employee form arch in hr_views.xml. The Odoo 20 section diffs the same files against the public development branch, where the Resource ref migration lands. Corrections welcome via our contact page.