Skip to Content
Menu
This question has been flagged
1 Odpoveď
741 Zobrazenia

I'm building a custom module for email templates for HR. My template file (hr_mail_template_mail_templates.xml) is this one:

<?xml version="1.0" encoding="utf-8"?>

<odoo>

  <data>

    <record id="mail_template_work_permit_expiry" model="mail.template">

      <field name="name">Work Permit Expiry Reminder</field>

      <field name="model_id" ref="hr.model_hr_employee"/>

      <field name="subject">Your Work Permit Expires Soon</field>

      <field name="body_html" type="html">

        <![CDATA[

          <p>Dear ${object.name},</p>

          <p>This is a reminder that your work permit is set to expire on <strong>${object.work_permit_expiration}</strong>.</p>

          <p>Please update your documents as soon as possible.</p>

          <p>Regards,<br/>HR Department</p>

        ]]>

      </field>

      <field name="email_to">${object.work_email}</field>

      <field name="email_from">${user.email}</field>

    </record>


    <record id="mail_template_performance_review" model="mail.template">

      <field name="name">Performance Review Notification</field>

      <field name="model_id" ref="hr.model_hr_employee"/>

      <field name="subject">Upcoming Performance Review</field>

      <field name="body_html" type="html">

        <![CDATA[

          <p>Hello ${object.parent_id.name},</p>

          <p>Please be reminded that <strong>${object.name}</strong>'s performance review is due soon.</p>

          <p>Kindly schedule the evaluation accordingly.</p>

          <p>Best regards,<br/>HR Department</p>

        ]]>

      </field>

      <field name="email_to">${object.parent_id.work_email}</field>

      <field name="email_from">${user.email}</field>

    </record> 

  </data>

</odoo>


When I try to activate the custom, show this error:

2025-07-02 16:56:09,236 4 ERROR nocllc-costex-migr18-20984680 odoo.tools.convert: The XML file '/home/odoo/src/user/hr_mail_template_control/data/hr_mail_template_mail_templates.xml' does not fit the required schema!

Traceback (most recent call last):

File "/home/odoo/src/odoo/odoo/tools/convert.py", line 669, in convert_xml_import

relaxng.assert_(doc)

File "src/lxml/etree.pyx", line 3682, in lxml.etree._Validator.assert_

AssertionError: Element odoo has extra content: data, line 3

2025-07-02 16:56:09,237 4 WARNING nocllc-costex-migr18-20984680 odoo.tools.convert: /home/odoo/src/user/hr_mail_template_control/data/hr_mail_template_mail_templates.xml:3:0:ERROR:RELAXNGV:RELAXNG_ERR_EXTRACONTENT: Element odoo has extra content: data

2025-07-02 16:56:09,237 4 INFO nocllc-costex-migr18-20984680 odoo.tools.convert: Install 'jingtrang' for more precise and useful validation messages.

2025-07-02 16:56:09,242 4 WARNING nocllc-costex-migr18-20984680 odoo.modules.loading: Transient module states were reset

2025-07-02 16:56:09,243 4 ERROR nocllc-costex-migr18-20984680 odoo.modules.registry: Failed to load registry

2025-07-02 16:56:09,245 4 INFO nocllc-costex-migr18-20984680 odoo.modules.loading: loading 1 modules...

2025-07-02 16:56:09,249 4 INFO nocllc-costex-migr18-20984680 odoo.modules.loading: 1 modules loaded in 0.00s, 0 queries (+0 extra)

2025-07-02 16:56:09,266 4 INFO nocllc-costex-migr18-20984680 odoo.modules.loading: loading 246 modules...

2025-07-02 16:56:09,365 4 INFO nocllc-costex-migr18-20984680 odoo.modules.loading: 246 modules loaded in 0.10s, 0 queries (+0 extra)

2025-07-02 16:56:09,616 4 INFO nocllc-costex-migr18-20984680 odoo.modules.loading: Modules loaded.

2025-07-02 16:56:09,623 4 INFO nocllc-costex-migr18-20984680 odoo.modules.registry: Registry loaded in 0.380s

2025-07-02 16:56:09,625 4 ERROR nocllc-costex-migr18-20984680 odoo.http: Exception during request handling.

Traceback (most recent call last):

File "/home/odoo/src/odoo/odoo/http.py", line 2532, in __call__

response = request._serve_db()

^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/http.py", line 2059, in _serve_db

return self._transactioning(

^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/http.py", line 2122, in _transactioning

return service_model.retrying(func, env=self.env)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/service/model.py", line 156, in retrying

result = func()

^^^^^^

File "/home/odoo/src/odoo/odoo/http.py", line 2089, in _serve_ir_http

response = self.dispatcher.dispatch(rule.endpoint, args)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/http.py", line 2337, in dispatch

result = self.request.registry['ir.http']._dispatch(endpoint)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/addons/base/models/ir_http.py", line 333, in _dispatch

result = endpoint(**request.params)

^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/http.py", line 754, in route_wrapper

result = endpoint(self, *args, **params_ok)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/addons/web/controllers/dataset.py", line 42, in call_button

action = call_kw(request.env[model], method, args, kwargs)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/api.py", line 533, in call_kw

result = getattr(recs, name)(*args, **kwargs)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/usr/lib/python3/dist-packages/decorator.py", line 232, in fun

return caller(func, *(extras + args), **kw)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/addons/base/models/ir_module.py", line 75, in check_and_log

return method(self, *args, **kwargs)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/addons/base/models/ir_module.py", line 480, in button_immediate_install

return self._button_immediate_function(self.env.registry[self._name].button_install)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/addons/base/models/ir_module.py", line 604, in _button_immediate_function

registry = modules.registry.Registry.new(self._cr.dbname, update_module=True)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/usr/lib/python3/dist-packages/decorator.py", line 232, in fun

return caller(func, *(extras + args), **kw)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/tools/func.py", line 97, in locked

return func(inst, *args, **kwargs)

^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/modules/registry.py", line 129, in new

odoo.modules.load_modules(registry, force_demo, status, update_module)

File "/home/odoo/src/odoo/odoo/modules/loading.py", line 484, in load_modules

processed_modules += load_marked_modules(env, graph,

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/modules/loading.py", line 365, in load_marked_modules

loaded, processed = load_module_graph(

^^^^^^^^^^^^^^^^^^

File "/home/odoo/src/odoo/odoo/modules/loading.py", line 228, in load_module_graph

load_data(env, idref, mode, kind='data', package=package)

File "/home/odoo/src/odoo/odoo/modules/loading.py", line 72, in load_data

tools.convert_file(env, package.name, filename, idref, mode, noupdate, kind)

File "/home/odoo/src/odoo/odoo/tools/convert.py", line 615, in convert_file

convert_xml_import(env, module, fp, idref, mode, noupdate)

File "/home/odoo/src/odoo/odoo/tools/convert.py", line 669, in convert_xml_import

relaxng.assert_(doc)

File "src/lxml/etree.pyx", line 3682, in lxml.etree._Validator.assert_

AssertionError: Element odoo has extra content: data, line 3


Any suggestions  it's appreciated,

Avatar
Zrušiť
Autor

Thanks for the instructions, it's working now

Best Answer

The suggested way of using variables in a template is to t-out' them (older versions of Odoo may require the use of t-esc instead).

Also, assigning values to fields should be done within using the {{ x }} notation, rather than ${x}.


<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <record id="mail_template_work_permit_expiry" model="mail.template">
            <field name="name">Work Permit Expiry Reminder</field>
            <field name="model_id" ref="hr.model_hr_employee"/>
            <field name="subject">Your Work Permit Expires Soon</field>
            <field name="body_html" type="html">
            <div>
                <p>Dear <t t-out="object.name or ''"/>,</p>
                <p>This is a reminder that your work permit is set to expire on <strong t-out="object.work_permit_expiration"/>.</p>
                <p>Please update your documents as soon as possible.</p>
                <p>Regards,<br/>HR Department</p>
            </div>
            </field>
            <field name="email_to">{{object.work_email}}</field>
            <field name="email_from">{{user.email}}</field>
        </record>

        <record id="mail_template_performance_review" model="mail.template">
            <field name="name">Performance Review Notification</field>
            <field name="model_id" ref="hr.model_hr_employee"/>
            <field name="subject">Upcoming Performance Review</field>
            <field name="body_html" type="html">
                <div>
                    <p>Hello <t t-out="object.parent_id.name or ''"/>,</p>
                    <p>Please be reminded that <strong t-out="object.name"/>'s performance review is due soon.</p>
                    <p>Kindly schedule the evaluation accordingly.</p>
                    <p>Best regards,<br/>HR Department</p>
                </div>
            </field>
            <field name="email_to">{{object.parent_id.work_email}}</field>
            <field name="email_from">{{user.email}}</field>
        </record>
    </data>
</odoo>
Avatar
Zrušiť