diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/website/models/theme_models.py | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/website/models/theme_models.py')
| -rw-r--r-- | addons/website/models/theme_models.py | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/addons/website/models/theme_models.py b/addons/website/models/theme_models.py new file mode 100644 index 00000000..848d3c57 --- /dev/null +++ b/addons/website/models/theme_models.py @@ -0,0 +1,289 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +from odoo import api, fields, models +from odoo.tools.translate import xml_translate +from odoo.modules.module import get_resource_from_path + +_logger = logging.getLogger(__name__) + + +class ThemeView(models.Model): + _name = 'theme.ir.ui.view' + _description = 'Theme UI View' + + def compute_arch_fs(self): + if 'install_filename' not in self._context: + return '' + path_info = get_resource_from_path(self._context['install_filename']) + if path_info: + return '/'.join(path_info[0:2]) + + name = fields.Char(required=True) + key = fields.Char() + type = fields.Char() + priority = fields.Integer(default=16, required=True) + mode = fields.Selection([('primary', "Base view"), ('extension', "Extension View")]) + active = fields.Boolean(default=True) + arch = fields.Text(translate=xml_translate) + arch_fs = fields.Char(default=compute_arch_fs) + inherit_id = fields.Reference(selection=[('ir.ui.view', 'ir.ui.view'), ('theme.ir.ui.view', 'theme.ir.ui.view')]) + copy_ids = fields.One2many('ir.ui.view', 'theme_template_id', 'Views using a copy of me', copy=False, readonly=True) + customize_show = fields.Boolean() + + def _convert_to_base_model(self, website, **kwargs): + self.ensure_one() + inherit = self.inherit_id + if self.inherit_id and self.inherit_id._name == 'theme.ir.ui.view': + inherit = self.inherit_id.with_context(active_test=False).copy_ids.filtered(lambda x: x.website_id == website) + if not inherit: + # inherit_id not yet created, add to the queue + return False + + if inherit and inherit.website_id != website: + website_specific_inherit = self.env['ir.ui.view'].with_context(active_test=False).search([ + ('key', '=', inherit.key), + ('website_id', '=', website.id) + ], limit=1) + if website_specific_inherit: + inherit = website_specific_inherit + + new_view = { + 'type': self.type or 'qweb', + 'name': self.name, + 'arch': self.arch, + 'key': self.key, + 'inherit_id': inherit and inherit.id, + 'arch_fs': self.arch_fs, + 'priority': self.priority, + 'active': self.active, + 'theme_template_id': self.id, + 'website_id': website.id, + 'customize_show': self.customize_show, + } + + if self.mode: # if not provided, it will be computed automatically (if inherit_id or not) + new_view['mode'] = self.mode + + return new_view + + +class ThemeAttachment(models.Model): + _name = 'theme.ir.attachment' + _description = 'Theme Attachments' + + name = fields.Char(required=True) + key = fields.Char(required=True) + url = fields.Char() + copy_ids = fields.One2many('ir.attachment', 'theme_template_id', 'Attachment using a copy of me', copy=False, readonly=True) + + + def _convert_to_base_model(self, website, **kwargs): + self.ensure_one() + new_attach = { + 'key': self.key, + 'public': True, + 'res_model': 'ir.ui.view', + 'type': 'url', + 'name': self.name, + 'url': self.url, + 'website_id': website.id, + 'theme_template_id': self.id, + } + return new_attach + + +class ThemeMenu(models.Model): + _name = 'theme.website.menu' + _description = 'Website Theme Menu' + + name = fields.Char(required=True, translate=True) + url = fields.Char(default='') + page_id = fields.Many2one('theme.website.page', ondelete='cascade') + new_window = fields.Boolean('New Window') + sequence = fields.Integer() + parent_id = fields.Many2one('theme.website.menu', index=True, ondelete="cascade") + copy_ids = fields.One2many('website.menu', 'theme_template_id', 'Menu using a copy of me', copy=False, readonly=True) + + def _convert_to_base_model(self, website, **kwargs): + self.ensure_one() + page_id = self.page_id.copy_ids.filtered(lambda x: x.website_id == website) + parent_id = self.copy_ids.filtered(lambda x: x.website_id == website) + new_menu = { + 'name': self.name, + 'url': self.url, + 'page_id': page_id and page_id.id or False, + 'new_window': self.new_window, + 'sequence': self.sequence, + 'parent_id': parent_id and parent_id.id or False, + 'theme_template_id': self.id, + } + return new_menu + + +class ThemePage(models.Model): + _name = 'theme.website.page' + _description = 'Website Theme Page' + + url = fields.Char() + view_id = fields.Many2one('theme.ir.ui.view', required=True, ondelete="cascade") + website_indexed = fields.Boolean('Page Indexed', default=True) + copy_ids = fields.One2many('website.page', 'theme_template_id', 'Page using a copy of me', copy=False, readonly=True) + + def _convert_to_base_model(self, website, **kwargs): + self.ensure_one() + view_id = self.view_id.copy_ids.filtered(lambda x: x.website_id == website) + if not view_id: + # inherit_id not yet created, add to the queue + return False + + new_page = { + 'url': self.url, + 'view_id': view_id.id, + 'website_indexed': self.website_indexed, + 'theme_template_id': self.id, + } + return new_page + + +class Theme(models.AbstractModel): + _name = 'theme.utils' + _description = 'Theme Utils' + _auto = False + + def _post_copy(self, mod): + # Call specific theme post copy + theme_post_copy = '_%s_post_copy' % mod.name + if hasattr(self, theme_post_copy): + _logger.info('Executing method %s' % theme_post_copy) + method = getattr(self, theme_post_copy) + return method(mod) + return False + + @api.model + def _reset_default_config(self): + # Reinitialize some css customizations + self.env['web_editor.assets'].make_scss_customization( + '/website/static/src/scss/options/user_values.scss', + { + 'font': 'null', + 'headings-font': 'null', + 'navbar-font': 'null', + 'buttons-font': 'null', + 'color-palettes-number': 'null', + 'btn-ripple': 'null', + 'header-template': 'null', + 'footer-template': 'null', + 'footer-scrolltop': 'null', + } + ) + + # Reinitialize effets + self.disable_view('website.option_ripple_effect') + + # Reinitialize header templates + self.enable_view('website.template_header_default') + self.disable_view('website.template_header_hamburger') + self.disable_view('website.template_header_vertical') + self.disable_view('website.template_header_sidebar') + self.disable_view('website.template_header_slogan') + self.disable_view('website.template_header_contact') + self.disable_view('website.template_header_minimalist') + self.disable_view('website.template_header_boxed') + self.disable_view('website.template_header_centered_logo') + self.disable_view('website.template_header_image') + self.disable_view('website.template_header_hamburger_full') + self.disable_view('website.template_header_magazine') + + # Reinitialize footer templates + self.enable_view('website.footer_custom') + self.disable_view('website.template_footer_descriptive') + self.disable_view('website.template_footer_centered') + self.disable_view('website.template_footer_links') + self.disable_view('website.template_footer_minimalist') + self.disable_view('website.template_footer_contact') + self.disable_view('website.template_footer_call_to_action') + self.disable_view('website.template_footer_headline') + + # Reinitialize footer scrolltop template + self.disable_view('website.option_footer_scrolltop') + + @api.model + def _toggle_view(self, xml_id, active): + obj = self.env.ref(xml_id) + website = self.env['website'].get_current_website() + if obj._name == 'theme.ir.ui.view': + obj = obj.with_context(active_test=False) + obj = obj.copy_ids.filtered(lambda x: x.website_id == website) + else: + # If a theme post copy wants to enable/disable a view, this is to + # enable/disable a given functionality which is disabled/enabled + # by default. So if a post copy asks to enable/disable a view which + # is already enabled/disabled, we would not consider it otherwise it + # would COW the view for nothing. + View = self.env['ir.ui.view'].with_context(active_test=False) + has_specific = obj.key and View.search_count([ + ('key', '=', obj.key), + ('website_id', '=', website.id) + ]) >= 1 + if not has_specific and active == obj.active: + return + obj.write({'active': active}) + + @api.model + def enable_view(self, xml_id): + self._toggle_view(xml_id, True) + + @api.model + def disable_view(self, xml_id): + self._toggle_view(xml_id, False) + + @api.model + def enable_header_off_canvas(self): + """ Enabling off canvas require to enable quite a lot of template so + this shortcut was made to make it easier. + """ + self.enable_view("website.option_header_off_canvas") + self.enable_view("website.option_header_off_canvas_template_header_hamburger") + self.enable_view("website.option_header_off_canvas_template_header_sidebar") + self.enable_view("website.option_header_off_canvas_template_header_hamburger_full") + + +class IrUiView(models.Model): + _inherit = 'ir.ui.view' + + theme_template_id = fields.Many2one('theme.ir.ui.view', copy=False) + + def write(self, vals): + no_arch_updated_views = other_views = self.env['ir.ui.view'] + for record in self: + # Do not mark the view as user updated if original view arch is similar + arch = vals.get('arch', vals.get('arch_base')) + if record.theme_template_id and record.theme_template_id.arch == arch: + no_arch_updated_views += record + else: + other_views += record + res = super(IrUiView, other_views).write(vals) + if no_arch_updated_views: + vals['arch_updated'] = False + res &= super(IrUiView, no_arch_updated_views).write(vals) + return res + +class IrAttachment(models.Model): + _inherit = 'ir.attachment' + + key = fields.Char(copy=False) + theme_template_id = fields.Many2one('theme.ir.attachment', copy=False) + + +class WebsiteMenu(models.Model): + _inherit = 'website.menu' + + theme_template_id = fields.Many2one('theme.website.menu', copy=False) + + +class WebsitePage(models.Model): + _inherit = 'website.page' + + theme_template_id = fields.Many2one('theme.website.page', copy=False) |
