[IMP] mail: add first lightweight support of qweb in rendering mixin
PURPOSE
Make digest email and tips more appealing. The goals of these tips are
* to encourage the adoption of other apps (Did you know ?);
* to make Odoo look more fun (Fun tips and tricks, young and dynamic style);
* to show social proof and increase trust (emphasis on already existing
projects / customers to);
SPECIFICATIONS
In this commit we simply add a first support of tools to render qweb templates
like rendering jinja. Instead of giving the template to render the xml id of
the view is passed.
This code is meant to be improved in a near future with new use cases that
will soon arise.
LINKS
Task ID 2197417
PR odoo/odoo#51619
This commit is contained in:
@@ -183,10 +183,74 @@ class MailRenderMixin(models.AbstractModel):
|
||||
|
||||
return html
|
||||
|
||||
@api.model
|
||||
def _render_encapsulate(self, layout_xmlid, html, add_context=None, context_record=None):
|
||||
try:
|
||||
template = self.env.ref(layout_xmlid, raise_if_not_found=True)
|
||||
except ValueError:
|
||||
_logger.warning('QWeb template %s not found when rendering encapsulation template.' % (layout_xmlid))
|
||||
else:
|
||||
record_name = context_record.display_name if context_record else ''
|
||||
model_description = self.env['ir.model']._get(context_record._name).display_name if context_record else False
|
||||
template_ctx = {
|
||||
'body': html,
|
||||
'record_name': record_name,
|
||||
'model_description': model_description,
|
||||
'company': context_record['company_id'] if (context_record and 'company_id' in context_record) else self.env.company,
|
||||
'record': context_record,
|
||||
}
|
||||
if add_context:
|
||||
template_ctx.update(**add_context)
|
||||
|
||||
html = template._render(template_ctx, engine='ir.qweb', minimal_qcontext=True)
|
||||
html = self.env['mail.render.mixin']._replace_local_links(html)
|
||||
return html
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# RENDERING
|
||||
# ------------------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def _render_qweb_eval_context(self):
|
||||
""" Prepare qweb evaluation context, containing for all rendering
|
||||
|
||||
* ``user``: current user browse record;
|
||||
* ``ctx```: current context;
|
||||
* various formatting tools;
|
||||
"""
|
||||
render_context = {
|
||||
'format_date': lambda date, date_format=False, lang_code=False: format_date(self.env, date, date_format, lang_code),
|
||||
'format_datetime': lambda dt, tz=False, dt_format=False, lang_code=False: format_datetime(self.env, dt, tz, dt_format, lang_code),
|
||||
'format_amount': lambda amount, currency, lang_code=False: tools.format_amount(self.env, amount, currency, lang_code),
|
||||
'format_duration': lambda value: tools.format_duration(value),
|
||||
'user': self.env.user,
|
||||
'ctx': self._context,
|
||||
}
|
||||
return render_context
|
||||
|
||||
@api.model
|
||||
def _render_template_qweb(self, template_src, model, res_ids, add_context=None):
|
||||
view = self.env.ref(template_src, raise_if_not_found=False) or self.env['ir.ui.view']
|
||||
results = dict.fromkeys(res_ids, u"")
|
||||
if not view:
|
||||
return results
|
||||
|
||||
# prepare template variables
|
||||
variables = self._render_qweb_eval_context()
|
||||
if add_context:
|
||||
variables.update(**add_context)
|
||||
|
||||
for record in self.env[model].browse(res_ids):
|
||||
variables['object'] = record
|
||||
try:
|
||||
render_result = view._render(variables, engine='ir.qweb', minimal_qcontext=True)
|
||||
except Exception as e:
|
||||
_logger.info("Failed to render template : %s (%d)" % (template_src, view.id), exc_info=True)
|
||||
raise UserError(_("Failed to render template : %s (%d)") % (template_src, view.id))
|
||||
results[record.id] = render_result
|
||||
|
||||
return results
|
||||
|
||||
@api.model
|
||||
def _render_jinja_eval_context(self):
|
||||
""" Prepare jinja evaluation context, containing for all rendering
|
||||
@@ -207,7 +271,7 @@ class MailRenderMixin(models.AbstractModel):
|
||||
return render_context
|
||||
|
||||
@api.model
|
||||
def _render_template_jinja(self, template_txt, model, res_ids):
|
||||
def _render_template_jinja(self, template_txt, model, res_ids, add_context=None):
|
||||
""" Render a string-based template on records given by a model and a list
|
||||
of IDs, using jinja.
|
||||
|
||||
@@ -238,6 +302,9 @@ class MailRenderMixin(models.AbstractModel):
|
||||
|
||||
# prepare template variables
|
||||
variables = self._render_jinja_eval_context()
|
||||
if add_context:
|
||||
variables.update(**add_context)
|
||||
|
||||
# TDE CHECKME
|
||||
# records = self.env[model].browse(it for it in res_ids if it) # filter to avoid browsing [None]
|
||||
if any(r is None for r in res_ids):
|
||||
@@ -271,11 +338,12 @@ class MailRenderMixin(models.AbstractModel):
|
||||
return rendered
|
||||
|
||||
@api.model
|
||||
def _render_template(self, template_txt, model, res_ids, engine='jinja', post_process=False):
|
||||
def _render_template(self, template_src, model, res_ids, engine='jinja', add_context=None, post_process=False):
|
||||
""" Render the given string on records designed by model / res_ids using
|
||||
the given rendering engine. Currently only jinja is supported.
|
||||
|
||||
:param str template_txt: template text to render
|
||||
:param str template_src: template text to render (jinja) or xml id of view (qweb)
|
||||
this could be cleaned but hey, we are in a rush
|
||||
:param str model: model name of records on which we want to perform rendering
|
||||
:param list res_ids: list of ids of records (all belonging to same model)
|
||||
:param string engine: jinja
|
||||
@@ -286,10 +354,13 @@ class MailRenderMixin(models.AbstractModel):
|
||||
"""
|
||||
if not isinstance(res_ids, (list, tuple)):
|
||||
raise ValueError(_('Template rendering should be called only using on a list of IDs.'))
|
||||
if engine != 'jinja':
|
||||
raise ValueError(_('Template rendering supports only jinja.'))
|
||||
if engine not in ('jinja', 'qweb'):
|
||||
raise ValueError(_('Template rendering supports only jinja or qweb.'))
|
||||
|
||||
rendered = self._render_template_jinja(template_txt, model, res_ids)
|
||||
if engine == 'qweb':
|
||||
rendered = self._render_template_qweb(template_src, model, res_ids, add_context=add_context)
|
||||
else:
|
||||
rendered = self._render_template_jinja(template_src, model, res_ids, add_context=add_context)
|
||||
if post_process:
|
||||
rendered = self._render_template_postprocess(rendered)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user