# Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models class PagePropertiesBase(models.TransientModel): _name = 'website.page.properties.base' _description = "Page Properties Base" target_model_id = fields.Reference(selection='_selection_target_model_id', required=True) website_id = fields.Many2one('website', required=True) menu_ids = fields.One2many('website.menu', compute='_compute_menu_ids') is_in_menu = fields.Boolean(compute='_compute_is_in_menu', inverse='_inverse_is_in_menu') url = fields.Char(required=True) is_homepage = fields.Boolean(compute='_compute_is_homepage', inverse='_inverse_is_homepage', string='Homepage') can_publish = fields.Boolean(compute='_compute_can_publish') is_published = fields.Boolean(compute='_compute_is_published', inverse='_inverse_is_published') def _selection_target_model_id(self): return [(model.model, model.name) for model in self.env['ir.model'].sudo().search([])] @api.depends('url', 'website_id') def _compute_menu_ids(self): for record in self: record.menu_ids = self.env['website.menu'].search([ ('website_id', '=', record.website_id.id), ('url', '=', record.url), ]) @api.depends('menu_ids') def _compute_is_in_menu(self): for record in self: record.is_in_menu = bool(record.menu_ids) def _inverse_is_in_menu(self): self.ensure_one() if self.is_in_menu: if not self.menu_ids: target = self.target_model_id self.env['website.menu'].create({ 'name': self.target_model_id.name, 'url': self.url, 'parent_id': self.website_id.menu_id.id, 'website_id': self.website_id.id, 'page_id': target.id if target._name == 'website.page' else False, }) elif self.menu_ids: # If the page is no longer in menu, that menu has to be removed self.menu_ids.unlink() @api.depends('url', 'website_id.homepage_url') def _compute_is_homepage(self): for record in self: url = record.url current_homepage_url = record.website_id.homepage_url or '/' # If the url field matches the website's homepage_url, we know this # is the homepage. # However, the url field contains the url of the accessed route. # Therefore, being on '/' means we went through the homepage # controller and the request was rerouted. record.is_homepage = url == current_homepage_url or url == '/' def _inverse_is_homepage(self): self.ensure_one() url = self.url if self.is_homepage: if url and url != '/': self.website_id.homepage_url = url else: self.website_id.homepage_url = False @api.depends('target_model_id') def _compute_can_publish(self): for record in self: target = record.target_model_id if target._name == 'ir.ui.view': # Check we are in a non-custom state to avoid messing with # manually set values. record.can_publish = self._is_ir_ui_view_published(target) or self._is_ir_ui_view_unpublished(target) # FIXME disabled for the moment because it does not hide the url # in the sitemap and it is difficult to find a fix that would be # consistent. To revisit later. record.can_publish = False elif 'can_publish' in target._fields: record.can_publish = target.can_publish else: record.can_publish = False @api.depends('target_model_id') def _compute_is_published(self): for record in self: target = record.target_model_id if target._name == 'ir.ui.view': record.is_published = self._is_ir_ui_view_published(target) elif 'is_published' in target._fields: record.is_published = target.is_published else: record.is_published = False def _inverse_is_published(self): self.ensure_one() target = self.target_model_id if target._name == 'ir.ui.view': if self.can_publish: if self.is_published: # Publish target.visibility = '' target.groups_id -= self._get_ir_ui_view_unpublish_group() else: # Unpublish target.visibility = 'restricted_group' target.groups_id += self._get_ir_ui_view_unpublish_group() self.env.registry.clear_cache('templates') elif 'is_published' in target._fields: target.is_published = self.is_published def _get_ir_ui_view_unpublish_group(self): return self.env.ref('base.group_user') def _is_ir_ui_view_unpublished(self, view): view.ensure_one() return (view.visibility == 'restricted_group' and self._get_ir_ui_view_unpublish_group() in view.groups_id) def _is_ir_ui_view_published(self, view): view.ensure_one() return not view.visibility class PageProperties(models.TransientModel): _name = 'website.page.properties' _description = "Page Properties" _inherit = [ 'website.page.properties.base', ] target_model_id = fields.Many2one('website.page') name = fields.Char(related='target_model_id.name', readonly=False) url = fields.Char(related='target_model_id.url', readonly=False) date_publish = fields.Datetime(related='target_model_id.date_publish', readonly=False) website_indexed = fields.Boolean(related='target_model_id.website_indexed', readonly=False) visibility = fields.Selection(related='target_model_id.visibility', readonly=False) visibility_password_display = fields.Char(related='target_model_id.visibility_password_display', readonly=False) groups_id = fields.Many2many(related='target_model_id.groups_id', readonly=False) is_new_page_template = fields.Boolean(related='target_model_id.is_new_page_template', readonly=False) old_url = fields.Char() redirect_old_url = fields.Boolean(default=False, store=False) redirect_type = fields.Selection( [ ('301', '301 Moved permanently'), ('302', '302 Moved temporarily'), ], default='301', store=False, required=True, ) @api.depends('url', 'website_id.homepage_url') def _compute_is_homepage(self): """ Don't match is_homepage when url is '/' as this model's url is not the accessed route's url. """ for record in self: url = record.url current_homepage_url = record.website_id.homepage_url or '/' record.is_homepage = url == current_homepage_url @api.model_create_multi def create(self, vals_list): records = super().create(vals_list) for record in records: record.old_url = record.url return records def write(self, vals): write_result = super().write(vals) # Once website.page has been written, the url might have been modified. # We can now create the redirects. if 'url' in vals: for record in self: old_url = record.old_url new_url = record.url if old_url != new_url: if vals.get('redirect_old_url'): website_id = vals.get('website_id') or record.website_id.id or False self.env['website.rewrite'].create( { 'name': vals.get('name') or record.name, 'redirect_type': vals.get('redirect_type') or record.redirect_type, 'url_from': old_url, 'url_to': new_url, 'website_id': website_id, } ) record.old_url = new_url return write_result