The html_translate fields (e.g. website_descripton on product.product) were not
serialised and the raw value from the web_editor was saved as a translation.
This was an issue in case of special characters that may be present in the
translation. A translation containing non-breaking space was sent in html
(`foo bar`) while lxml converts such characters to unicode (`foo\xa0bar`).
When writing a translation, the value is checked against incorrect format using
```
value0 = field.translate(lambda term: None, record[fname])
value1 = field.translate({trans.src: trans.value}.get, value0)
value2 = field.translate({trans.value: trans.src}.get, value1)
if value2 != value0:
raise ValidationError(_("Translation is not valid:\n%s") % trans.value)
```
As value1 is the unicode version of the translation and `trans.value` is the
html version of the translation, the last substitution in the callback method
was never made and the ValidationError was raised.
This commit forces the serialisation through lxml to be sure the compared
strings are using the same parser instead of comparing value from summernote and
lxml that may be both valid but still different.
opw-675767
46 lines
2.0 KiB
Python
46 lines
2.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from lxml import etree
|
|
|
|
from openerp import models, api
|
|
from openerp.tools.translate import encode, xml_translate, html_translate
|
|
|
|
def edit_translation_mapping(data):
|
|
data = dict(data, model=data['name'].partition(',')[0])
|
|
return '<span data-oe-model="%(model)s" data-oe-translation-id="%(id)s" data-oe-translation-state="%(state)s">%(value)s</span>' % data
|
|
|
|
class ir_translation(models.Model):
|
|
_inherit = 'ir.translation'
|
|
|
|
@api.model
|
|
def _get_terms_mapping(self, field, records):
|
|
if self._context.get('edit_translations'):
|
|
self.insert_missing(field, records)
|
|
return edit_translation_mapping
|
|
return super(ir_translation, self)._get_terms_mapping(field, records)
|
|
|
|
@api.multi
|
|
def save_html(self, value):
|
|
""" Convert the HTML fragment ``value`` to XML if necessary, and write
|
|
it as the value of translation ``self``.
|
|
"""
|
|
assert len(self) == 1 and self.type == 'model'
|
|
mname, fname = self.name.split(',')
|
|
field = self.env[mname]._fields[fname]
|
|
if field.translate == xml_translate:
|
|
# wrap value inside a div and parse it as HTML
|
|
div = "<div>%s</div>" % encode(value)
|
|
root = etree.fromstring(div, etree.HTMLParser(encoding='utf-8'))
|
|
# root is html > body > div
|
|
# serialize div as XML and discard surrounding tags
|
|
value = etree.tostring(root[0][0], encoding='utf-8')[5:-6]
|
|
elif field.translate == html_translate:
|
|
# wrap value inside a div and parse it as HTML
|
|
div = "<div>%s</div>" % encode(value)
|
|
root = etree.fromstring(div, etree.HTMLParser(encoding='utf-8'))
|
|
# root is html > body > div
|
|
# serialize div as HTML and discard surrounding tags
|
|
value = etree.tostring(root[0][0], encoding='utf-8', method='html')[5:-6]
|
|
return self.write({'value': value})
|