From e84a72767ec3fad0fa1b31613fb737c7ca605f9d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 2 Jul 2021 08:51:14 +0000 Subject: [PATCH] [FIX] website: de-traw-ify dynamic snippets Mark the fragments as markup-safe after fetching them. Also make _render private (don't see any reason for it to be publicly accessible), and avoid unnecessary intermediate enc/dec in it. --- addons/website/controllers/main.py | 2 +- .../website/models/website_snippet_filter.py | 6 ++-- .../src/snippets/s_dynamic_snippet/000.js | 36 ++++++++----------- .../src/snippets/s_dynamic_snippet/000.xml | 2 +- .../s_dynamic_snippet_carousel/000.xml | 2 +- 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 1607253d126..7955e9018cd 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -308,7 +308,7 @@ class Website(Home): dynamic_filter = request.env['website.snippet.filter'].sudo().search( [('id', '=', filter_id)] + request.website.website_domain() ) - return dynamic_filter and dynamic_filter.render(template_key, limit, search_domain, with_sample) or '' + return dynamic_filter and dynamic_filter._render(template_key, limit, search_domain, with_sample) or '' @http.route('/website/snippet/options_filters', type='json', auth='user', website=True) def get_dynamic_snippet_filters(self, model_name=None, search_domain=None): diff --git a/addons/website/models/website_snippet_filter.py b/addons/website/models/website_snippet_filter.py index 6f0d0e8b83e..a14af39197d 100644 --- a/addons/website/models/website_snippet_filter.py +++ b/addons/website/models/website_snippet_filter.py @@ -55,7 +55,7 @@ class WebsiteSnippetFilter(models.Model): if not field_name.strip(): raise ValidationError(_("Empty field name in %r") % (record.field_names)) - def render(self, template_key, limit, search_domain=None, with_sample=False): + def _render(self, template_key, limit, search_domain=None, with_sample=False): """Renders the website dynamic snippet items""" self.ensure_one() assert '.dynamic_filter_template_' in template_key, _("You can only use template prefixed by dynamic_filter_template_ ") @@ -76,8 +76,8 @@ class WebsiteSnippetFilter(models.Model): content = View._render_template(template_key, dict( records=records, is_sample=is_sample, - )).decode('utf-8') - return [ET.tostring(el, encoding='utf-8') for el in ET.fromstring('%s' % content).getchildren()] + )) + return [ET.tostring(el, encoding='unicode') for el in ET.fromstring(b'%s' % content).getchildren()] def _prepare_values(self, limit=None, search_domain=None): """Gets the data and returns it the right format for render.""" diff --git a/addons/website/static/src/snippets/s_dynamic_snippet/000.js b/addons/website/static/src/snippets/s_dynamic_snippet/000.js index 4a532fc8abd..e807637d38e 100644 --- a/addons/website/static/src/snippets/s_dynamic_snippet/000.js +++ b/addons/website/static/src/snippets/s_dynamic_snippet/000.js @@ -4,6 +4,7 @@ odoo.define('website.s_dynamic_snippet', function (require) { const core = require('web.core'); const config = require('web.config'); const publicWidget = require('web.public.widget'); +const {Markup} = require('web.utils'); const DynamicSnippet = publicWidget.Widget.extend({ selector: '.s_dynamic_snippet', @@ -110,29 +111,22 @@ const DynamicSnippet = publicWidget.Widget.extend({ * Fetches the data. * @private */ - _fetchData: function () { + async _fetchData() { if (this._isConfigComplete()) { - return this._rpc( - { - 'route': '/website/snippet/filters', - 'params': Object.assign({ - 'filter_id': parseInt(this.$el.get(0).dataset.filterId), - 'template_key': this.$el.get(0).dataset.templateKey, - 'limit': parseInt(this.$el.get(0).dataset.numberOfRecords), - 'search_domain': this._getSearchDomain(), - 'with_sample': this.editableMode, - }, this._getRpcParameters()), - }) - .then( - (data) => { - this.data = data; - } - ); - } else { - return new Promise((resolve) => { - this.data = []; - resolve(); + const nodeData = this.el.dataset; + const filterFragments = await this._rpc({ + 'route': '/website/snippet/filters', + 'params': Object.assign({ + 'filter_id': parseInt(nodeData.filterId), + 'template_key': nodeData.templateKey, + 'limit': parseInt(nodeData.numberOfRecords), + 'search_domain': this._getSearchDomain(), + 'with_sample': this.editableMode, + }, this._getRpcParameters()), }); + this.data = filterFragments.map(Markup); + } else { + this.data = []; } }, /** diff --git a/addons/website/static/src/snippets/s_dynamic_snippet/000.xml b/addons/website/static/src/snippets/s_dynamic_snippet/000.xml index 9d73d41d8e0..68153dd3453 100644 --- a/addons/website/static/src/snippets/s_dynamic_snippet/000.xml +++ b/addons/website/static/src/snippets/s_dynamic_snippet/000.xml @@ -10,7 +10,7 @@
- +
diff --git a/addons/website/static/src/snippets/s_dynamic_snippet_carousel/000.xml b/addons/website/static/src/snippets/s_dynamic_snippet_carousel/000.xml index 0a69cbadb1b..075aebf97f3 100644 --- a/addons/website/static/src/snippets/s_dynamic_snippet_carousel/000.xml +++ b/addons/website/static/src/snippets/s_dynamic_snippet_carousel/000.xml @@ -13,7 +13,7 @@
- +