Exemplo n.º 1
0
    def _render_template_qweb_view(self,
                                   template_src,
                                   model,
                                   res_ids,
                                   add_context=None,
                                   options=None):
        """ Render a QWeb template based on an ir.ui.view content.

        In addition to the generic evaluation context available, some other
        variables are added:
          * ``object``: record based on which the template is rendered;

        :param str template_src: source QWeb template. It should be a string
          XmlID allowing to fetch an ``ir.ui.view``;
        :param str model: see ``MailRenderMixin._render_template()``;
        :param list res_ids: see ``MailRenderMixin._render_template()``;

        :param dict add_context: additional context to give to renderer. It
          allows to add or update values to base rendering context generated
          by ``MailRenderMixin._render_qweb_eval_context()``;
        :param dict options: options for rendering (not used currently);

        :return dict: {res_id: string of rendered template based on record}
        """
        # prevent wrong values (rendering on a void record set, ...)
        if any(r is None for r in res_ids):
            raise ValueError(
                _('Template rendering should be called on a valid record IDs.')
            )

        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)
        safe_eval.check_values(variables)

        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 : %(xml_id)s (%(view_id)d)",
                      xml_id=template_src,
                      view_id=view.id))
            results[record.id] = render_result

        return results
Exemplo n.º 2
0
    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.

        In addition to the generic evaluation context given by _render_jinja_eval_context
        some new variables are added, depending on each record

          * ``object``: record based on which the template is rendered;

        :param str template_txt: template text to render
        :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)

        :return dict: {res_id: string of rendered template based on record}
        """
        # TDE FIXME: remove that brol (6dde919bb9850912f618b561cd2141bffe41340c)
        no_autoescape = self._context.get('safe')
        results = dict.fromkeys(res_ids, u"")
        if not template_txt:
            return results

        # try to load the template
        try:
            jinja_env = jinja_safe_template_env if no_autoescape else jinja_template_env
            template = jinja_env.from_string(tools.ustr(template_txt))
        except Exception:
            _logger.info("Failed to load template %r",
                         template_txt,
                         exc_info=True)
            return results

        # prepare template variables
        variables = self._render_jinja_eval_context()
        if add_context:
            variables.update(**add_context)
        safe_eval.check_values(variables)

        # 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):
            raise ValueError(_('Unsuspected None'))

        for record in self.env[model].browse(res_ids):
            variables['object'] = record
            try:
                render_result = template.render(variables)
            except Exception as e:
                _logger.info("Failed to render template : %s" % e,
                             exc_info=True)
                raise UserError(_("Failed to render template : %s", e))
            if render_result == u"False":
                render_result = u""
            results[record.id] = render_result

        return results
Exemplo n.º 3
0
    def _prepare_values(self, values, options):
        """ Prepare the context that will be sent to the evaluated function.

        :param values: template values to be used for rendering
        :param options: frozen dict of compilation parameters.
        """
        check_values(values)
        values['true'] = True
        values['false'] = False
        if 'request' not in values:
            values['request'] = request
        return super()._prepare_values(values, options)
Exemplo n.º 4
0
    def _render_template_jinja(self,
                               template_txt,
                               model,
                               res_ids,
                               add_context=None,
                               options=None):
        """ Render a string-based template on records given by a model and a list
        of IDs, using jinja.

        In addition to the generic evaluation context available, some other
        variables are added:
          * ``object``: record based on which the template is rendered;

        :param str template_txt: template text to render
        :param str model: see ``MailRenderMixin._render_template()``;
        :param list res_ids: see ``MailRenderMixin._render_template()``;

        :param dict add_context: additional context to give to renderer. It
          allows to add or update values to base rendering context generated
          by ``MailRenderMixin._render_jinja_eval_context()``;
        :param dict options: options for rendering;

        :return dict: {res_id: string of rendered template based on record}
        """
        # prevent wrong values (rendering on a void record set, ...)
        if any(r is None for r in res_ids):
            raise ValueError(
                _('Template rendering should be called on a valid record IDs.')
            )

        # TDE note: support 'safe' context key as backward compatibility for 6dde919bb9850912f618b561cd2141bffe41340c
        if options is None:
            options = {}
        no_autoescape = options.get('render_safe') or self._context.get('safe')

        results = dict.fromkeys(res_ids, u"")
        if not template_txt:
            return results

        # try to load the template
        try:
            jinja_env = jinja_safe_template_env if no_autoescape else jinja_template_env
            template = jinja_env.from_string(tools.ustr(template_txt))
        except Exception:
            _logger.info("Failed to load template %r",
                         template_txt,
                         exc_info=True)
            return results

        if (not self._unrestricted_rendering and template.is_dynamic
                and not self.env.is_admin() and
                not self.env.user.has_group('mail.group_mail_template_editor')
            ):
            group = self.env.ref('mail.group_mail_template_editor')
            raise AccessError(
                _(
                    'Only users belonging to the "%s" group can modify dynamic templates.',
                    group.name))

        if not template.is_dynamic:
            # Either the content is a raw text without placeholders, either we fail to
            # detect placeholders code. In both case we skip the rendering and return
            # the raw content, so even if we failed to detect dynamic code,
            # non "mail_template_editor" users will not gain rendering tools available
            # only for template specific group users
            return {record_id: template_txt for record_id in res_ids}

        # prepare template variables
        variables = self._render_jinja_eval_context()
        if add_context:
            variables.update(**add_context)
        safe_eval.check_values(variables)

        for record in self.env[model].browse(res_ids):
            variables['object'] = record
            try:
                render_result = template.render(variables)
            except Exception as e:
                _logger.info("Failed to render template : %s",
                             e,
                             exc_info=True)
                raise UserError(_("Failed to render template : %s", e))
            if render_result == u"False":
                render_result = u""
            results[record.id] = Markup(render_result)

        return results
Exemplo n.º 5
0
    def _render_template_jinja(self,
                               template_txt,
                               model,
                               res_ids,
                               add_context=None,
                               options=None):
        """ Render a string-based template on records given by a model and a list
        of IDs, using jinja.

        In addition to the generic evaluation context available, some other
        variables are added:
          * ``object``: record based on which the template is rendered;

        :param str template_txt: template text to render
        :param str model: see ``MailRenderMixin._render_template()``;
        :param list res_ids: see ``MailRenderMixin._render_template()``;

        :param dict add_context: additional context to give to renderer. It
          allows to add or update values to base rendering context generated
          by ``MailRenderMixin._render_jinja_eval_context()``;
        :param dict options: options for rendering;

        :return dict: {res_id: string of rendered template based on record}
        """
        # prevent wrong values (rendering on a void record set, ...)
        if any(r is None for r in res_ids):
            raise ValueError(
                _('Template rendering should be called on a valid record IDs.')
            )

        # TDE note: support 'safe' context key as backward compatibility for 6dde919bb9850912f618b561cd2141bffe41340c
        if options is None:
            options = {}
        no_autoescape = options.get('render_safe') or self._context.get('safe')

        results = dict.fromkeys(res_ids, u"")
        if not template_txt:
            return results

        # try to load the template
        try:
            jinja_env = jinja_safe_template_env if no_autoescape else jinja_template_env
            template = jinja_env.from_string(tools.ustr(template_txt))
        except Exception:
            _logger.info("Failed to load template %r",
                         template_txt,
                         exc_info=True)
            return results

        # prepare template variables
        variables = self._render_jinja_eval_context()
        if add_context:
            variables.update(**add_context)
        safe_eval.check_values(variables)

        for record in self.env[model].browse(res_ids):
            variables['object'] = record
            try:
                render_result = template.render(variables)
            except Exception as e:
                _logger.info("Failed to render template : %s",
                             e,
                             exc_info=True)
                raise UserError(_("Failed to render template : %s", e))
            if render_result == u"False":
                render_result = u""
            results[record.id] = Markup(render_result)

        return results