diff --git a/addons/web_editor/controllers/main.py b/addons/web_editor/controllers/main.py index 02d46a7d7bd..012082b332b 100644 --- a/addons/web_editor/controllers/main.py +++ b/addons/web_editor/controllers/main.py @@ -289,7 +289,8 @@ class Web_Editor(http.Controller): excluded_url_matcher = re.compile("^(.+/lib/.+)|(.+import_bootstrap.+\.scss)$") # Load already customized scss files attachments - custom_attachments = request.env["ir.attachment"].search([("url", "=like", self._make_custom_scss_file_url("%%.%%", "%%"))]) + custom_url = self._make_custom_scss_file_url("%%.%%", "%%") + custom_attachments = self.get_custom_attachment(custom_url, op='=like') # First check the t-call-assets used in the related views url_infos = dict() @@ -379,6 +380,12 @@ class Web_Editor(http.Controller): scss = get_scss and scss_files_data_by_bundle or [], ) + def save_scss_view_hook(self): + return {} + + def save_scss_attachment_hook(self): + return {} + ## The save_scss route is in charge of saving a given modification of a scss file. ## @param url - the original url of the scss file which has to be modified ## @param bundle_xmlid - the xmlid of the bundle in which the scss file addition can be found @@ -390,45 +397,47 @@ class Web_Editor(http.Controller): custom_url = self._make_custom_scss_file_url(url, bundle_xmlid) # Check if the file to save had already been modified - custom_attachment = IrAttachment.search([("url", "=", custom_url)]) + custom_attachment = self.get_custom_attachment(custom_url) datas = base64.b64encode((content or "\n").encode("utf-8")) if custom_attachment: # If it was already modified, simply override the corresponding attachment content custom_attachment.write({"datas": datas}) else: # If not, create a new attachment to copy the original scss file content, with its modifications - IrAttachment.create(dict( - name = custom_url, - type = "binary", - mimetype = "text/scss", - datas = datas, - datas_fname = url.split("/")[-1], - url = custom_url, # Having an attachment of "binary" type with an non empty "url" field - # is quite of an hack. This allows to fetch the "datas" field by adding - # a with the "url" content in the bundle template (see qweb) - )) + new_attach = { + 'name': custom_url, + 'type': "binary", + 'mimetype': "text/scss", + 'datas': datas, + 'datas_fname': url.split("/")[-1], + 'url': custom_url, + } + new_attach.update(self.save_scss_attachment_hook()) + IrAttachment.create(new_attach) # Create a view to extend the template which adds the original file to link the new modified version instead IrUiView = request.env["ir.ui.view"] view_to_xpath = IrUiView.get_related_views(bundle_xmlid, bundles=True).filtered(lambda v: v.arch.find(url) >= 0) - IrUiView.create(dict( - name = custom_url, - key='web_editor.scss_%s' % str(uuid.uuid4())[:6], - mode = "extension", - inherit_id = view_to_xpath.id, - arch = """ + new_view = { + 'name': custom_url, + 'key': 'web_editor.scss_%s' % str(uuid.uuid4())[:6], + 'mode': "extension", + 'inherit_id': view_to_xpath.id, + 'arch': """ %(new_url)s - """ % dict( - inherit_xml_id = view_to_xpath.xml_id, - name = custom_url, - url_to_replace = url, - new_url = custom_url, - ) - )) + """ % { + 'inherit_xml_id': view_to_xpath.xml_id, + 'name': custom_url, + 'url_to_replace': url, + 'new_url': custom_url, + } + } + new_view.update(self.save_scss_view_hook()) + IrUiView.create(new_view) request.env["ir.qweb"].clear_caches() @@ -437,14 +446,21 @@ class Web_Editor(http.Controller): ## @param bundle_xmlid - the xmlid of the bundle in which the scss file addition can be found @http.route("/web_editor/reset_scss", type="json", auth="user") def reset_scss(self, url, bundle_xmlid): - IrAttachment = request.env["ir.attachment"] - IrUiView = request.env["ir.ui.view"] - custom_url = self._make_custom_scss_file_url(url, bundle_xmlid) # Simply delete the attachement which contains the modified scss file and the xpath view which links it - IrAttachment.search([("url", "=", custom_url)]).unlink() - IrUiView.search([("name", "=", custom_url)]).unlink() + self.get_custom_attachment(custom_url).unlink() + self.get_custom_view(custom_url).unlink() + + def get_custom_attachment(self, custom_url, op='like'): + assert op in ('like', '=like', '='), 'Invalid operator' + IrAttachment = request.env["ir.attachment"] + return IrAttachment.search([("url", op, custom_url)]) + + def get_custom_view(self, custom_url, op='='): + assert op in ('like', '=ilike', '='), 'Invalid operator' + IrUiView = request.env["ir.ui.view"] + return IrUiView.search([("name", op, custom_url)]) def _make_custom_scss_file_url(self, url, bundle): parts = url.rsplit(".", 1) @@ -455,9 +471,9 @@ class Web_Editor(http.Controller): m = self._match_scss_file_url_regex.match(url) if not m: return False - return dict( - module = m.group(1), - resource_path = "%s.%s" % (m.group(2), m.group(5)), - customized = bool(m.group(3)), - bundle = m.group(4) or False - ) + return { + 'module': m.group(1), + 'resource_path': "%s.%s" % (m.group(2), m.group(5)), + 'customized': bool(m.group(3)), + 'bundle': m.group(4) or False + } diff --git a/addons/website/controllers/__init__.py b/addons/website/controllers/__init__.py index 5ee7aaab8f2..9b1d03120de 100644 --- a/addons/website/controllers/__init__.py +++ b/addons/website/controllers/__init__.py @@ -3,3 +3,4 @@ from . import backend from . import main +from . import web_editor diff --git a/addons/website/controllers/web_editor.py b/addons/website/controllers/web_editor.py new file mode 100644 index 00000000000..d70e912018b --- /dev/null +++ b/addons/website/controllers/web_editor.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.web_editor.controllers.main import Web_Editor +from odoo.http import request + + +class Web_Editor(Web_Editor): + + def save_scss_view_hook(self): + res = super(Web_Editor, self).save_scss_view_hook() + + website = request.env['website'].get_current_website() + if website: + res['website_id'] = website.id + return res + + def save_scss_attachment_hook(self): + res = super(Web_Editor, self).save_scss_attachment_hook() + + website = request.env['website'].get_current_website() + if website: + res['website_id'] = website.id + return res + + def get_custom_attachment(self, custom_url, op='like'): + website = request.env['website'].get_current_website() + res = super(Web_Editor, self).get_custom_attachment(custom_url, op=op) + return res.with_context(website_id=website.id).filtered(lambda x: not x.website_id or x.website_id == website) + + def get_custom_view(self, custom_url, op='='): + website = request.env['website'].get_current_website() + res = super(Web_Editor, self).get_custom_view(custom_url, op=op) + return res.with_context(website_id=website.id).filter_duplicate() diff --git a/addons/website/models/ir_attachment.py b/addons/website/models/ir_attachment.py index 02a678ad9ec..f49611e6e05 100644 --- a/addons/website/models/ir_attachment.py +++ b/addons/website/models/ir_attachment.py @@ -3,6 +3,8 @@ import logging from odoo import fields, models, api +from odoo.exceptions import UserError +from odoo.tools.translate import _ _logger = logging.getLogger(__name__)