Overview
QWeb is Odoo’s XML-based templating engine used to render backend views, website pages, and PDF reports. It processes XML templates and evaluates Python expressions inside special attributes prefixed with t-.
These t- attributes control logic, iteration, variable assignment, field formatting, dynamic HTML attributes, and template composition. Understanding them is essential for building clean and maintainable Odoo templates.
t-out
Outputs escaped content. This prevents HTML injection and is safe for displaying text.
<span t-out="o.name"/>
if o.name is "John Doe", it renders:
<span>John Doe</span>
Use this when you want to safely display values.
t-esc
Alias of t-out. It behaves exactly the same.
t-raw
Outputs unescaped HTML. This should only be used when the content is trusted.
<div t-raw="o.note"/>
If o.note = "<b>Important</b>", it renders bold text.
Avoid using this with user-generated content.
t-if
Renders the element only if the condition is True.
<div t-if="o.state == 'done'">
Completed
</div>
If the condition is False, the element is completely removed from the final output.
t-elif
Used after t-if for additional conditions.
<div t-if="o.state == 'draft'">Draft</div>
<div t-elif="o.state == 'done'">Done</div>
t-else
Fallback condition.
<div t-if="o.amount_total > 0">
Has Amount
</div>
<div t-else="">
No Amount
</div>
t-foreach
Iterates over a collection.
<tr t-foreach="o.order_line" t-as="line">
<td t-out="line.name"/>
<td t-out="line.price_unit"/>
</tr>
- t-foreach defines the iterable
- t-as defines the loop variable
t-set
Defines a variable inside the template.
<t t-set="total" t-value="sum(o.order_line.mapped('price_total'))"/>
<span t-out="total"/>
Useful for pre-calculations or simplifying expressions.
t-call
Calls another template.
<t t-call="web.basic_layout">
<div class="page">
Content here
</div>
</t>
t-field
Renders model fields with automatic formatting based on field type.
<span t-field="o.amount_total"/>
Currency formatting is applied automatically.
t-options
Used with t-field to customize rendering.
<span t-field="o.amount_total"
t-options="{'widget': 'monetary',
'display_currency': o.currency_id}"
/>
t-att-*
Dynamically sets a specific attribute.
<img t-att-src="'/web/image/res.partner/%s/image_1920' % o.partner_id.id"/>
Here, the src attribute is generated dynamically.
t-attf-*
Formatted string version of t-att-*.
<div t-attf-class="badge badge-#{o.state}">
Useful for composing dynamic class names.
t-att
Assigns multiple attributes dynamically using a dictionary.
<div t-att="{'data-id': o.id, 'class': 'custom-class'}"/>
Notes
QWeb t- attributes control every aspect of template rendering in Odoo. They allow:
- Conditional rendering
- Looping through records
- Variable creation
- Template composition
- Field formatting
- Dynamic HTML generation
Mastering them is essential for building advanced reports, backend customizations, and clean Odoo modules!
