[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:
committed by
Jeremy Kersten
parent
ff3c494448
commit
eee1b39806
@@ -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>
|
||||
|
||||
@@ -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'))
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user