Odoo18-Base/addons/website/models/website_page_properties.py
2025-01-06 10:57:38 +07:00

202 lines
8.2 KiB
Python

# 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