Skip to content

Odoo glossary

QWeb

Also called Odoo QWeb, QWeb report, QWeb template

Definition

QWeb is Odoo's XML templating engine. A QWeb template is ordinary XML or HTML with t- directives such as t-if, t-foreach, t-out and t-call, and Odoo uses it to render PDF reports and website and portal pages on the server and, through OWL, the web client's components in the browser.

If you’ve changed what a quotation PDF prints, you’ve touched QWeb. The same syntax also drives website pages and the whole web client, but two different engines render it, and mixing them up is where most of the confusion starts.

Two engines, one syntax

On the server, ir.qweb renders templates stored as views. Reports go through it, get wrapped in a layout and are turned into PDF by wkhtmltopdf. Website and portal pages use the same Python engine. In the browser, OWL compiles QWeb templates from your addon’s static XML files into components.

Most directives work on both sides, but not all. t-field, which formats a record field according to its type and can take t-options such as a widget, is Python only. t-name, t-inherit and t-inherit-mode are how static JavaScript templates are named and extended.

The directives that do the work

t-if, t-elif and t-else handle conditions. t-foreach with t-as loops, and gives you extra variables like line_index, line_first and line_last when you write t-as="line". t-set with t-value stores a value. t-call renders another template, and whatever you put inside the call is available there as 0. t-att-href computes an attribute value, and t-attf-class builds one from a format string.

For output, use t-out. It escapes HTML unless the value is already marked safe, such as an HTML field or a markupsafe.Markup. t-esc still works as an alias and the docs haven’t formally deprecated it, but they list it under deprecated output directives, so new code should say t-out. t-raw was deprecated in Odoo 15.

Adding a line to the quotation PDF

The sale order document, sale.report_saleorder_document, has a div with id="informations" holding the reference and date blocks in 17, 18 and 19. That id makes a steady anchor:

<template id="report_saleorder_document_delivery_window"
          inherit_id="sale.report_saleorder_document">
    <xpath expr="//div[@id='informations']" position="inside">
        <div t-if="doc.delivery_window" class="col" name="informations_delivery_window">
            <strong>Delivery window</strong>
            <div t-field="doc.delivery_window"/>
        </div>
    </xpath>
</template>

doc is the variable the sale report sets inside its loop over docs. The positions and locators are the ones described under XPath view inheritance. The inner classes around that div changed between 17 and 18, so check the rendered PDF on each version you support.

Where QWeb work goes wrong

Copying the whole template. Duplicating report_saleorder_document to change one line means the next Odoo release’s fixes never reach your copy. Inherit and xpath instead. That’s how erpfly delivers report changes in the addons it generates, and our Odoo customization page walks through a fuller quotation example.

Custom report models that lose docs. If you define report.<module>.<report_name> with _get_report_values, Odoo stops providing docs, doc_ids and doc_model for you. Return them yourself, or any template that loops over docs breaks.

Expecting t-lang everywhere. Translating a report into the partner’s language works by putting t-lang on a t-call. On any other element it won’t translate anything.

Wrapping values in Markup to silence escaping. It tells QWeb the content is safe without checking. For anything a user typed, that’s an XSS hole.

If you’re coming from ERPNext, the closest counterpart is the Print Format, which uses Jinja rather than XML directives.

Sources

The official documentation and source code this page was checked against.

  1. 01 QWeb Templates, Odoo 19 developer documentation odoo.com
  2. 02 QWeb Reports, Odoo 19 developer documentation odoo.com
  3. 03 addons/sale/report/ir_actions_report_templates.xml (19.0), odoo/odoo on GitHub github.com

Where QWeb comes up

Terms used on this page

More Odoo terms

Your next module is one paragraph away

Write it the way you’d explain it to a new hire. We’ll turn it into an app you can read, test and install.

Odoo 19

Create your account

Free to start. No card needed.

By signing up you agree to our terms and privacy policy.