diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py
index 0b5945c1f0b..afcda2b6efd 100644
--- a/addons/email_template/email_template.py
+++ b/addons/email_template/email_template.py
@@ -24,6 +24,8 @@ import base64
import datetime
import dateutil.relativedelta as relativedelta
import logging
+import lxml
+import urlparse
import openerp
from openerp import SUPERUSER_ID
@@ -70,6 +72,7 @@ try:
except ImportError:
_logger.warning("jinja2 not available, templating features will not work!")
+
class email_template(osv.osv):
"Templates for sending email"
_name = "email.template"
@@ -82,7 +85,48 @@ class email_template(osv.osv):
res['model_id'] = self.pool['ir.model'].search(cr, uid, [('model', '=', res.pop('model'))], context=context)[0]
return res
- def render_template_batch(self, cr, uid, template, model, res_ids, context=None):
+ def _replace_local_links(self, cr, uid, html, context=None):
+ """ Post-processing of html content to replace local links to absolute
+ links, using web.base.url as base url. """
+ if not html:
+ return html
+
+ # form a tree
+ root = lxml.html.fromstring(html)
+ if not len(root) and root.text is None and root.tail is None:
+ html = '
%s
' % html
+ root = lxml.html.fromstring(html)
+
+ base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
+ (base_scheme, base_netloc, bpath, bparams, bquery, bfragment) = urlparse.urlparse(base_url)
+
+ def _process_link(url):
+ new_url = url
+ (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
+ if not scheme and not netloc:
+ new_url = urlparse.urlunparse((base_scheme, base_netloc, path, params, query, fragment))
+ return new_url
+
+ # check all nodes, replace :
+ # - img src -> check URL
+ # - a href -> check URL
+ for node in root.iter():
+ if node.tag == 'a':
+ node.set('href', _process_link(node.get('href')))
+ elif node.tag == 'img' and not node.get('src', 'data').startswith('data'):
+ node.set('src', _process_link(node.get('src')))
+
+ html = lxml.html.tostring(root, pretty_print=False, method='html')
+ # this is ugly, but lxml/etree tostring want to put everything in a 'div' that breaks the editor -> remove that
+ if html.startswith('') and html.endswith('
'):
+ html = html[5:-6]
+ return html
+
+ def render_post_process(self, cr, uid, html, context=None):
+ html = self._replace_local_links(cr, uid, html, context=context)
+ return html
+
+ def render_template_batch(self, cr, uid, template, model, res_ids, context=None, post_process=False):
"""Render the given template text, replace mako expressions ``${expr}``
with the result of evaluating these expressions with
an evaluation context containing:
@@ -125,6 +169,10 @@ class email_template(osv.osv):
if render_result == u"False":
render_result = u""
results[res_id] = render_result
+
+ if post_process:
+ for res_id, result in results.iteritems():
+ results[res_id] = self.render_post_process(cr, uid, result, context=context)
return results
def get_email_template_batch(self, cr, uid, template_id=False, res_ids=None, context=None):
@@ -356,17 +404,20 @@ class email_template(osv.osv):
results = dict()
for template, template_res_ids in templates_to_res_ids.iteritems():
# generate fields value for all res_ids linked to the current template
- for field in ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to']:
- generated_field_values = self.render_template_batch(cr, uid, getattr(template, field), template.model, template_res_ids, context=context)
+ for field in fields:
+ generated_field_values = self.render_template_batch(
+ cr, uid, getattr(template, field), template.model, template_res_ids,
+ post_process=(field == 'body_html'),
+ context=context)
for res_id, field_value in generated_field_values.iteritems():
results.setdefault(res_id, dict())[field] = field_value
# update values for all res_ids
for res_id in template_res_ids:
values = results[res_id]
- if template.user_signature:
+ if 'body_html' in fields and template.user_signature:
signature = self.pool.get('res.users').browse(cr, uid, uid, context).signature
values['body_html'] = tools.append_content_to_html(values['body_html'], signature)
- if values['body_html']:
+ if values.get('body_html'):
values['body'] = tools.html_sanitize(values['body_html'])
values.update(
mail_server_id=template.mail_server_id.id or False,
diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py
index beede1122dc..71f99471afa 100644
--- a/addons/email_template/wizard/mail_compose_message.py
+++ b/addons/email_template/wizard/mail_compose_message.py
@@ -162,16 +162,18 @@ class mail_compose_message(osv.TransientModel):
partner_ids += self.pool['res.partner'].exists(cr, SUPERUSER_ID, tpl_partner_ids, context=context)
return partner_ids
- def generate_email_for_composer_batch(self, cr, uid, template_id, res_ids, context=None):
+ def generate_email_for_composer_batch(self, cr, uid, template_id, res_ids, context=None, fields=None):
""" Call email_template.generate_email(), get fields relevant for
mail.compose.message, transform email_cc and email_to into partner_ids """
# filter template values
- fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'attachments', 'mail_server_id']
+ if fields is None:
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'mail_server_id']
+ returned_fields = fields + ['attachments']
values = dict.fromkeys(res_ids, False)
- template_values = self.pool.get('email.template').generate_email_batch(cr, uid, template_id, res_ids, context=context)
+ template_values = self.pool.get('email.template').generate_email_batch(cr, uid, template_id, res_ids, fields=fields, context=context)
for res_id in res_ids:
- res_id_values = dict((field, template_values[res_id][field]) for field in fields if template_values[res_id].get(field))
+ res_id_values = dict((field, template_values[res_id][field]) for field in returned_fields if template_values[res_id].get(field))
res_id_values['body'] = res_id_values.pop('body_html', '')
# transform email_to, email_cc into partner_ids
@@ -189,7 +191,10 @@ class mail_compose_message(osv.TransientModel):
""" Override to handle templates. """
# generate template-based values
if wizard.template_id:
- template_values = self.generate_email_for_composer_batch(cr, uid, wizard.template_id.id, res_ids, context=context)
+ template_values = self.generate_email_for_composer_batch(
+ cr, uid, wizard.template_id.id, res_ids,
+ fields=['email_to', 'partner_to', 'email_cc', 'attachment_ids', 'mail_server_id'],
+ context=context)
else:
template_values = dict.fromkeys(res_ids, dict())
# generate composer values
@@ -206,8 +211,8 @@ class mail_compose_message(osv.TransientModel):
template_values[res_id].update(composer_values[res_id])
return template_values
- def render_template_batch(self, cr, uid, template, model, res_ids, context=None):
- return self.pool.get('email.template').render_template_batch(cr, uid, template, model, res_ids, context=context)
+ def render_template_batch(self, cr, uid, template, model, res_ids, context=None, post_process=False):
+ return self.pool.get('email.template').render_template_batch(cr, uid, template, model, res_ids, context=context, post_process=post_process)
# Compatibility methods
def generate_email_for_composer(self, cr, uid, template_id, res_id, context=None):
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index 2d09a925ca7..e5ff2b51fcd 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -352,10 +352,10 @@ class mail_compose_message(osv.TransientModel):
:return dict results: for each res_id, the generated template values for
subject, body, email_from and reply_to
"""
- subjects = self.render_template_batch(cr, uid, wizard.subject, wizard.model, res_ids, context)
- bodies = self.render_template_batch(cr, uid, wizard.body, wizard.model, res_ids, context)
- emails_from = self.render_template_batch(cr, uid, wizard.email_from, wizard.model, res_ids, context)
- replies_to = self.render_template_batch(cr, uid, wizard.reply_to, wizard.model, res_ids, context)
+ subjects = self.render_template_batch(cr, uid, wizard.subject, wizard.model, res_ids, context=context)
+ bodies = self.render_template_batch(cr, uid, wizard.body, wizard.model, res_ids, context=context, post_process=True)
+ emails_from = self.render_template_batch(cr, uid, wizard.email_from, wizard.model, res_ids, context=context)
+ replies_to = self.render_template_batch(cr, uid, wizard.reply_to, wizard.model, res_ids, context=context)
results = dict.fromkeys(res_ids, False)
for res_id in res_ids:
@@ -367,7 +367,7 @@ class mail_compose_message(osv.TransientModel):
}
return results
- def render_template_batch(self, cr, uid, template, model, res_ids, context=None):
+ def render_template_batch(self, cr, uid, template, model, res_ids, context=None, post_process=False):
""" Render the given template text, replace mako-like expressions ``${expr}``
with the result of evaluating these expressions with an evaluation context
containing:
diff --git a/addons/website_mail/models/email_template.py b/addons/website_mail/models/email_template.py
index aed01c179f7..beb02739f29 100644
--- a/addons/website_mail/models/email_template.py
+++ b/addons/website_mail/models/email_template.py
@@ -19,9 +19,6 @@
#
##############################################################################
-import lxml
-import urlparse
-
from openerp.osv import osv, fields
from openerp.tools.translate import _
@@ -39,52 +36,3 @@ class EmailTemplate(osv.Model):
help='Link to the website',
),
}
-
- def _postprocess_html_replace_links(self, cr, uid, body_html, context=None):
- """ Post-processing of body_html. Indeed the content generated by the
- website builder contains references to local addresses, for example
- for images. This method changes those addresses to absolute addresses. """
- html = body_html
- if not body_html:
- return html
-
- # form a tree
- root = lxml.html.fromstring(html)
- if not len(root) and root.text is None and root.tail is None:
- html = '%s
' % html
- root = lxml.html.fromstring(html)
-
- base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
- (base_scheme, base_netloc, bpath, bparams, bquery, bfragment) = urlparse.urlparse(base_url)
-
- def _process_link(url):
- new_url = url
- (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
- if not scheme and not netloc:
- new_url = urlparse.urlunparse((base_scheme, base_netloc, path, params, query, fragment))
- return new_url
-
- # check all nodes, replace :
- # - img src -> check URL
- # - a href -> check URL
- for node in root.iter():
- if node.tag == 'a':
- node.set('href', _process_link(node.get('href')))
- elif node.tag == 'img' and not node.get('src', 'data').startswith('data'):
- node.set('src', _process_link(node.get('src')))
-
- html = lxml.html.tostring(root, pretty_print=False, method='html')
- # this is ugly, but lxml/etree tostring want to put everything in a 'div' that breaks the editor -> remove that
- if html.startswith('') and html.endswith('
'):
- html = html[5:-6]
- return html
-
- def create(self, cr, uid, values, context=None):
- if 'body_html' in values:
- values['body_html'] = self._postprocess_html_replace_links(cr, uid, values['body_html'], context=context)
- return super(EmailTemplate, self).create(cr, uid, values, context=context)
-
- def write(self, cr, uid, ids, values, context=None):
- if 'body_html' in values:
- values['body_html'] = self._postprocess_html_replace_links(cr, uid, values['body_html'], context=context)
- return super(EmailTemplate, self).write(cr, uid, ids, values, context=context)