[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.
This commit is contained in:
Xavier Morel
2021-07-20 05:45:52 +00:00
parent cb5695f46f
commit e84a72767e
5 changed files with 21 additions and 27 deletions
+1 -1
View File
@@ -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):
@@ -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('<root>%s</root>' % content).getchildren()]
))
return [ET.tostring(el, encoding='unicode') for el in ET.fromstring(b'<root>%s</root>' % content).getchildren()]
def _prepare_values(self, limit=None, search_domain=None):
"""Gets the data and returns it the right format for render."""
@@ -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 = [];
}
},
/**
@@ -10,7 +10,7 @@
<t t-foreach="colIndexGenerator" t-as="colIndex">
<t t-if="(rowIndex * chunkSize + colIndex) &lt; data.length">
<div t-attf-class="#{colClass}">
<t t-raw="data[rowIndex * chunkSize + colIndex]"/>
<t t-out="data[rowIndex * chunkSize + colIndex]"/>
</div>
</t>
</t>
@@ -13,7 +13,7 @@
<t t-foreach="itemIndexGenerator" t-as="itemIndex">
<t t-if="(slideIndex * chunkSize + itemIndex) &lt; data.length">
<div t-attf-class="#{colClass}">
<t t-raw="data[slideIndex * chunkSize + itemIndex]"/>
<t t-out="data[slideIndex * chunkSize + itemIndex]"/>
</div>
</t>
</t>