[FIX] ir_qweb: post process the attributes in widget html value

issue: Blog doe not use the cdn because the widget html value is not
compiled by the qweb and does not use the attribute post processing.
This commit is contained in:
Christophe Matthieu
2018-06-15 08:42:15 +02:00
committed by Jeremy Kersten
parent ff3c494448
commit eee1b39806
5 changed files with 44 additions and 7 deletions
@@ -26,6 +26,9 @@
<img src="/website/static/img.png"/>
<a href="http://test.external.link/link">x</a>
<a href="/web/content/local_link">x</a>
<span t-attf-style="background-image: url('/web/image/2')" t-att-empty="False">xxx</span>
<div widget="html" t-field="user.signature"/>
<div widget="image" t-field="user.image" t-options="{'widget': 'image'}"/>
</body>
</html>
</template>
+22 -5
View File
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import re
from odoo import tools
from odoo.modules.module import get_module_resource
from odoo.tests.common import TransactionCase
@@ -22,18 +24,24 @@ class TestQweb(TransactionCase):
})
demo = self.env['res.users'].search([('login', '=', 'demo')])[0]
demo.write({"signature": '''<span class="toto">
span<span class="fa"></span><img src="/web/image/1"/>
</span>'''})
demo_env = self.env(user=demo)
html = demo_env['ir.qweb'].render('website.test_template', {}, website_id= website.id)
html = demo_env['ir.qweb'].render('website.test_template', {"user": demo}, website_id= website.id)
html = html.strip().decode('utf8')
html = re.sub(r'\?unique=[^"]+', '', html).encode('utf8')
attachments = demo_env['ir.attachment'].search([('url', '=like', '/web/content/%-%/website.test_bundle.%')])
self.assertEquals(len(attachments), 2)
self.assertEqual(html.strip(), """<!DOCTYPE html>
self.assertEqual(len(attachments), 2)
self.assertEqual(html, ("""<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://test.external.link/style1.css"/>
<link rel="stylesheet" href="http://test.external.link/style2.css"/>
<link href="http://test.cdn%(css)s" rel="stylesheet"/>
<link type="text/css" rel="stylesheet" href="http://test.cdn%(css)s"/>
<meta/>
<script type="text/javascript" src="http://test.external.link/javascript1.js"></script>
<script type="text/javascript" src="http://test.external.link/javascript2.js"></script>
@@ -44,5 +52,14 @@ class TestQweb(TransactionCase):
<img src="http://test.cdn/website/static/img.png"/>
<a href="http://test.external.link/link">x</a>
<a href="http://test.cdn/web/content/local_link">x</a>
<span style="background-image: url('http://test.cdn/web/image/2')">xxx</span>
<div widget="html"><span class="toto">
span<span class="fa"></span><img src="http://test.cdn/web/image/1">
</span></div>
<div widget="image"><img src="http://test.cdn/web/image/res.users/%(user_id)s/image" class="img img-responsive"/></div>
</body>
</html>""" % {"js": attachments[0].url, "css": attachments[1].url})
</html>""" % {
"js": attachments[0].url,
"css": attachments[1].url,
"user_id": demo.id,
}).encode('utf8'))
+13 -1
View File
@@ -6,6 +6,8 @@ from io import BytesIO
from odoo import api, fields, models, _
from PIL import Image
import babel
from lxml import etree
from odoo.tools import html_escape as escape, posix_to_ldml, safe_eval, float_utils, format_date, pycompat
import logging
@@ -252,7 +254,17 @@ class HTMLConverter(models.AbstractModel):
@api.model
def value_to_html(self, value, options):
return pycompat.to_text(value)
irQweb = self.env['ir.qweb']
# wrap value inside a body and parse it as HTML
body = etree.fromstring("<body>%s</body>" % value, etree.HTMLParser(encoding='utf-8'))[0]
# use pos processing for all nodes with attributes
for element in body.iter():
if element.attrib:
attrib = OrderedDict(element.attrib)
attrib = irQweb._post_processing_att(element.tag, attrib, options)
element.attrib.clear()
element.attrib.update(attrib)
return etree.tostring(body, encoding='unicode', method='html')[6:-7]
class ImageConverter(models.AbstractModel):
+5
View File
@@ -341,6 +341,11 @@ class IrQWeb(models.AbstractModel, QWeb):
def _get_field(self, record, field_name, expression, tagName, field_options, options, values):
field = record._fields[field_name]
# adds template compile options for rendering fields
for k, v in options.items():
field_options.setdefault(k, v)
# adds generic field options
field_options['tagName'] = tagName
field_options['expression'] = expression
field_options['type'] = field_options.get('widget', field.type)
+1 -1
View File
@@ -5,7 +5,7 @@ import os.path
import re
import traceback
from collections import OrderedDict, Sized, Mapping, defaultdict
from collections import OrderedDict, Sized, Mapping
from functools import reduce
from itertools import tee, count
from textwrap import dedent