Email sales@vrajatechnologies.com Teams Teams Contact +91 9099928101 Whatsapp +91 73596 28466 Linkedin Linkdin
Email Template Rendering with Jinja and Safe Evaluation in Odoo?

✅ Overview

Odoo uses Jinja2 templating and safe evaluation context to dynamically render email content such as:
  • Subject
  • Body (HTML/text)
  • Sender and recipient addresses
This allows emails to be personalized per record (e.g., customer name, product details) using secure and controlled access to model fields and functions.

🔧 Where Jinja Is Used

Jinja expressions are commonly used in:

FieldUsed In
Subject{{ object.name }}
Email Body (HTML)<p>Hello {{ object.partner_id.name }}</p>
Sender Email{{ user.email }}
Email To / CC{{ object.user_id.email }}
 

📘 Basic Syntax of Jinja​

{{ object.name }}                   → Field value

{{ object.amount_total | float }}  → With filters

{% if object.state == ‘draft’ %}   → Conditional logic

  Draft Order

{% endif %}

🔒 Safe Evaluation (safe_eval)

Odoo restricts evaluation context to safe variables and methods only, to avoid security risks (e.g., executing arbitrary Python).

📌 Variables Available in Templates

Variable
Meaning
objectCurrent record (e.g., sale.order)
userCurrent user (record of res.users)
ctxCurrent context
format_tz()Format datetime with timezone
format_date()Format date
format_amount()Format currency

Example 1: Custom Email Body

<p>Hello {{ object.partner_id.name }},</p>

<p>Your order <strong>{{ object.name }}</strong> has been confirmed with a total of

<strong>{{ format_amount(object.amount_total, object.currency_id) }}</strong>.</p>

<p>Thanks,<br/>{{ user.company_id.name }}</p>

Example 2: Subject with Condition

{{ ‘New Quotation’ if object.state == ‘draft’ else ‘Confirmed Order’ }

Example 3: Dynamic From Address

{{ user.email }}

🛠 How Rendering Works in Python​

Odoo uses the render_template() function from mail.template:

template = self.env.ref(‘sale.email_template_edi_sale’)

body_html = template._render_template(template.body_html, ‘sale.order’, order.id)

🚫 Common Mistakes

Issue
Cause
UndefinedError: ‘object’ is undefinedTemplate used outside proper record context
Jinja syntax errorMissing {% endif %}, wrong brackets
HTML not rendering properlyWrong field used (body_text instead of body_html)

✅ Summary Table

Concept
Description
Jinja2Templating engine for email templates
objectRefers to the current record
userCurrent user (sender)
format_* funcsHelper functions to format values securely
safe_evalLimits evaluation to safe variables
render_template()Programmatic rendering of templates
 

🧠 Best Practices

  • Always use {{ }} for expressions and {% %} for control logic.
  • Use helper functions like format_amount() and format_date() instead of raw Python.
  • Avoid calling unsafe or complex methods directly inside the template.
  • Test templates via the “Send Test Email” feature in Developer Mode.