summaryrefslogtreecommitdiff
path: root/addons/web_editor/models
diff options
context:
space:
mode:
authorfja-odoo <fja@odoo.com>2019-11-15 16:13:17 +0000
committerqsm-odoo <qsm@odoo.com>2020-01-16 14:29:04 +0000
commit218e1cad6152999a0f41f073b5efa3c9428da48d (patch)
tree76ebfa75fcb86195fd4b4c14af7b87b8ad3920c8 /addons/web_editor/models
parent4946739c17488d32d3e61b1258ab48b5aec701a4 (diff)
[IMP] web_editor, *: allow saving of snippets
* website, mass_mailing, website_event, website_form, website_mass_mailing, website_sale Now the user can save snippets to use them on other pages. task-2120409 closes odoo/odoo#40408 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com> Co-authored-by: qsm-odoo <qsm@odoo.com>
Diffstat (limited to 'addons/web_editor/models')
-rw-r--r--addons/web_editor/models/ir_qweb.py5
-rw-r--r--addons/web_editor/models/ir_ui_view.py81
2 files changed, 83 insertions, 3 deletions
diff --git a/addons/web_editor/models/ir_qweb.py b/addons/web_editor/models/ir_qweb.py
index 78ebe9b2178..0cf3ff932c9 100644
--- a/addons/web_editor/models/ir_qweb.py
+++ b/addons/web_editor/models/ir_qweb.py
@@ -50,9 +50,10 @@ class QWeb(models.AbstractModel):
view_id = View.get_view_id(el.attrib.get('t-call'))
name = View.browse(view_id).name
thumbnail = el.attrib.pop('t-thumbnail', "oe-thumbnail")
- div = u'<div name="%s" data-oe-type="snippet" data-oe-thumbnail="%s">' % (
+ div = u'<div name="%s" data-oe-type="snippet" data-oe-thumbnail="%s" data-oe-snippet-id="%s">' % (
escape(pycompat.to_text(name)),
- escape(pycompat.to_text(thumbnail))
+ escape(pycompat.to_text(thumbnail)),
+ escape(pycompat.to_text(view_id)),
)
return [self._append(ast.Str(div))] + self._compile_node(el, options) + [self._append(ast.Str(u'</div>'))]
diff --git a/addons/web_editor/models/ir_ui_view.py b/addons/web_editor/models/ir_ui_view.py
index 0aefd108432..19470d40c3c 100644
--- a/addons/web_editor/models/ir_ui_view.py
+++ b/addons/web_editor/models/ir_ui_view.py
@@ -3,10 +3,11 @@
import copy
import logging
+import uuid
from lxml import etree, html
from odoo.exceptions import AccessError
-from odoo import api, fields, models
+from odoo import api, models
_logger = logging.getLogger(__name__)
@@ -271,3 +272,81 @@ class IrUiView(models.Model):
View = self.with_context(active_test=False, lang=None)
views = View._views_get(key, bundles=bundles)
return views.filtered(lambda v: not v.groups_id or len(user_groups.intersection(v.groups_id)))
+
+ # --------------------------------------------------------------------------
+ # Snippet saving
+ # --------------------------------------------------------------------------
+
+ @api.model
+ def _get_default_snippet_thumbnail(self, snippet_class=None):
+ return '/web_editor/static/src/img/snippets_thumbs/s_custom_snippet.png'
+
+ @api.model
+ def _get_snippet_addition_view_key(self, template_key, key):
+ return '%s.%s' % (template_key, key)
+
+ @api.model
+ def _snippet_save_view_values_hook(self):
+ return {}
+
+ @api.model
+ def save_snippet(self, name, arch, template_key, snippet_class=None, thumbnail_url=None):
+ """
+ Saves a new snippet arch so that it appears with the given name when
+ using the given snippets template.
+
+ :param name: the name of the snippet to save
+ :param arch: the html structure of the snippet to save
+ :param template_key: the key of the view regrouping all snippets in
+ which the snippet to save is meant to appear
+ :param snippet_class: a className which is supposed to uniquely-identify
+ the snippet from which the snippet to save originates
+ :param thumbnail_url: the url of the thumbnail to use when displaying
+ the snippet to save (default: see '_get_default_snippet_thumbnail')
+ """
+ if not thumbnail_url:
+ thumbnail_url = self._get_default_snippet_thumbnail(snippet_class)
+
+ app_name = template_key.split('.')[0]
+ snippet_class = snippet_class or 's_custom_snippet'
+ key = '%s_%s' % (snippet_class, uuid.uuid4().hex)
+ snippet_key = '%s.%s' % (app_name, key)
+
+ # html to xml to add '/' at the end of self closing tags like br, ...
+ xml_arch = etree.tostring(html.fromstring(arch))
+ new_snippet_view_values = {
+ 'name': name,
+ 'key': snippet_key,
+ 'type': 'qweb',
+ 'arch': xml_arch,
+ }
+ new_snippet_view_values.update(self._snippet_save_view_values_hook())
+ self.create(new_snippet_view_values)
+
+ custom_section = self.search([('key', '=', template_key)])
+ snippet_addition_view_values = {
+ 'name': name + ' Block',
+ 'key': self._get_snippet_addition_view_key(template_key, key),
+ 'inherit_id': custom_section.id,
+ 'type': 'qweb',
+ 'arch': """
+ <data inherit_id="%s">
+ <xpath expr="//div[@id='snippet_custom']" position="attributes">
+ <attribute name="class" remove="d-none" separator=" "/>
+ </xpath>
+ <xpath expr="//div[@id='snippet_custom_body']" position="inside">
+ <t t-snippet="%s" t-thumbnail="%s"/>
+ </xpath>
+ </data>
+ """ % (template_key, snippet_key, thumbnail_url),
+ }
+ snippet_addition_view_values.update(self._snippet_save_view_values_hook())
+ self.create(snippet_addition_view_values)
+
+ @api.model
+ def delete_snippet(self, view_id, template_key):
+ snippet_view = self.browse(view_id)
+ key = snippet_view.key.split('.')[1]
+ custom_key = self._get_snippet_addition_view_key(template_key, key)
+ snippet_addition_view = self.search([('key', '=', custom_key)])
+ (snippet_addition_view | snippet_view).unlink()