Communication is a silent but essential facet of the day-to-day business operations process. Thus, emails form a fundamental platform in a system-oriented communication scenario, whether it is with regard to a sales order confirmation, a customer notification related to an invoice, or even a notification related to employee leave approval. At this juncture, emails can be referred to as contextual, dynamic, and intricately related to data in a business scenario in relation to Odoo. Of course, at this juncture in the scenario, dynamic placeholders in emails play a vital role in assuring emails that are relevant rather than robotic in nature.
Dynamic placeholders are helpful for software developers and functional users to effectively insert significant real-time customer information, such as customer names, order numbers, dates, money amounts, responsible users, etc., into the email templates without the use of any programming code. In this blog, we will explain what exactly dynamic placeholders are, how they really work, etc., in the context of Odoo version 19.
What Are Dynamic Placeholders in Odoo?
In Odoo, dynamic placeholders are variables used inside an email template to auto-populate their values from the current record at the time of sending. This way, instead of saying "Dear Customer", "Your order reference is SO0001", the system will dynamically replace those values concerning the actual data.
In simple terms, placeholders act like bridges between the database and the email body. When an email is triggered—manually or automatically—Odoo evaluates the placeholders and replaces them with real values from the related model record.
For example:
- Customer name comes from the partner record
- Order number comes from the sales order
- Total amount comes from the invoice or order lines
This mechanism ensures consistency, reduces manual errors, and saves a significant amount of time in routine communications.
Where Are Email Templates Used in Odoo 19?
Email templates in Odoo are widely used across multiple modules. Some common areas include:
- Sales Orders (quotation confirmation, order confirmation)
- Invoicing and Accounting (invoice sent, payment reminder)
- CRM (lead follow-ups, activity reminders)
- HR (leave approvals, contract notifications)
- Purchase Orders (RFQs, vendor confirmations)
- Automated actions and scheduled jobs
Each of these templates relies heavily on dynamic placeholders to stay relevant to the record being processed.
Understanding the Placeholder Syntax
Odoo email templates primarily use QWeb expressions and Python-style object references. In Odoo 19, the most commonly used syntax looks like this:
${object.field_name}Here:
- object refers to the active record (for example, a sale order or invoice)
- field_name refers to a specific field on that record
This syntax may look simple, but it is powerful enough to access related records, computed fields, and even nested data.
Commonly Used Dynamic Placeholders
Below are some frequently used placeholders that work across many models.
Basic Record Information
- ${object.name}
Displays the record name (e.g., Sales Order number, Invoice number).
- ${object.date_order}
Useful in sales and purchase orders to show the order date.
- ${object.state}
Shows the current status of the document.
These placeholders are often used in subject lines to give instant context.
Partner and Customer-Related Placeholders
Most business emails involve customers or vendors. Odoo stores this information in the partner_id field.
Examples:
${object.partner_id.name}
${object.partner_id.email}
${object.partner_id.phone}Usage example in an email body:
Dear ${object.partner_id.name},
Thank you for your recent order with us.
This small detail makes the email feel personal rather than automated.
User and Company Information
Sometimes, emails need to reflect who is responsible for the document or which company is sending it.
Common placeholders include:
${object.user_id.name}
${object.company_id.name}
${object.company_id.email}
${object.company_id.phone}These are especially useful in multi-company environments, where branding and sender details matter.
Monetary and Financial Fields
For invoices, quotations, and purchase orders, financial values are essential.
Examples:
${object.amount_total}
${object.amount_untaxed}
${object.currency_id.symbol}You can combine them naturally in text:
The total payable amount is ${object.amount_total} ${object.currency_id.symbol}.
This ensures accuracy and avoids mismatches caused by manual typing.
Line-Level Data Using Loops
One of the most powerful features of Odoo email templates is the ability to loop through record lines using QWeb.
For example, in a sales order email:
<t t-foreach="object.order_line" t-as="line">
- ${line.product_id.name}: ${line.product_uom_qty}
</t>
This permits dynamic listing of products, quantities, or prices without any hardcoding. It is widely used in order summaries and invoice breakdowns.
Conditional Content Using Logic
Odoo also supports conditional rendering in email templates.
Example:
<t t-if="object.payment_term_id">
Payment Terms: ${object.payment_term_id.name}
</t>
This makes sure that the optional information appears only if that information exists. For a user, the email feels clean and purposeful-not cluttered with fields of empty information.
Placeholders in Email Subjects
Dynamic placeholders are not limited to the email body. They are equally useful in the subject line.
Example subject:
Invoice ${object.name} from ${object.company_id.name}This will allow the recipient to recognize the purpose of the email instantly, especially when dealing with a lot of transactions.
Sample Email with Dynamic Placeholders
Below is a simple example of a mail template that is used in Odoo. I will use it to exemplify the use of dynamic placeholders. Again, I will use a simple scenario that all users get when they first want to use Odoo to confirm a Sales Order.
Email Subject
Order Confirmation - ${object.name}Email Body
Dear ${object.partner_id.name},
We are happy to confirm your order with reference ${object.name}, dated ${object.date_order}.
The total order value is ${object.amount_total} ${object.currency_id.symbol}.
Your order is being handled by ${object.user_id.name}.
If you need any clarification, please feel free to reach out to us.
Regards,
${object.company_id.name}A simple system message is transformed into a clear, contextual communication with the use of a few well-placed dynamic placeholders within this sample email.
The role of dynamic placeholders in the Odoo email system is subtle but significant because they enable relevant information to reach the concerned person without any manual intervention.
But once you understand these placeholders and how to use them properly, you can make use of email templates with ease and reliability, ensuring that Odoo communicates effectively while still closely tied to actual business data.
To read more about How to Create an Email Template in Odoo 19, refer to our blog How to Create an Email Template in Odoo 19.