[FIX] website: store default menu tree (apps menu) for new website

Previously, for multi-websites it was decided that:
  - creating a new website would not get already existing apps menu (shop,
    blog, forum..).
  - installing a new app would create the app's menu on existing website

This was decided mostly for technical reason but it is a weird behavior.

This commit saves the installed apps menus in order to copy them on new website
If this default menu got deleted, we ensure a minimalist tree menu for new
website

Note: This also fixes the bug where installing a website_module more than once
(with -i website_module in command line) would create the menu (blog, shop,
forum..) on the first website a second time.

This was because the website.menu.create() overrided in website would
return the last created record in the self loop, thus the last one created
would be the one set to the xml_id (ir.model.data).

This commit closes #27253
This commit is contained in:
Romain Derie
2018-09-29 17:56:21 +02:00
committed by Jeremy Kersten
parent 73f0cc21ce
commit 850e1675eb
4 changed files with 74 additions and 60 deletions
+24 -28
View File
@@ -1,17 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="default_website" model="website">
<field name="name">My Website</field>
<field name="domain"></field>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="base.public_user"/>
<field name="favicon" type="base64" file="web/static/src/img/favicon.ico"/>
</record>
<!-- Default Menu to store module menus for new website -->
<record id="main_menu" model="website.menu">
<field name="name">Top Menu</field>
<field name="website_id" ref="default_website"/>
<field name="name">Default Main Menu</field>
<field name="url">/default-main-menu</field>
</record>
<record id="menu_home" model="website.menu">
<field name="name">Home</field>
<field name="url">/</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">10</field>
</record>
<record id="menu_contactus" model="website.menu">
<field name="name">Contact us</field>
<field name="url">/contactus</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">60</field>
</record>
<!-- split between ir_ui_view & website_page record to keep external_id on ir_ui_view -->
@@ -35,16 +40,6 @@
<field name="url">/</field>
<field name="view_id" ref="homepage"/>
</record>
<record id="default_website" model="website">
<field name="homepage_id" ref="homepage_page"/>
</record>
<record id="menu_homepage" model="website.menu">
<field name="name">Home</field>
<field name="url">/</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">10</field>
<field name="page_id" ref="homepage_page"/>
</record>
<!-- Contact Us page -->
<record id="contactus" model="ir.ui.view">
@@ -103,14 +98,6 @@
<field name="website_published">True</field>
<field name="view_id" ref="contactus"/>
</record>
<record id="menu_contactus" model="website.menu">
<field name="name">Contact us</field>
<field name="url">/contactus</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">60</field>
<field name="page_id" ref="contactus_page"/>
<field name="website_id" ref="default_website"/>
</record>
<!-- About Us page -->
<record id="aboutus" model="ir.ui.view">
@@ -164,6 +151,15 @@
<field name="view_id" ref="aboutus"/>
</record>
<record id="default_website" model="website">
<field name="name">My Website</field>
<field name="domain"></field>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="base.public_user"/>
<field name="favicon" type="base64" file="web/static/src/img/favicon.ico"/>
<field name="homepage_id" ref="homepage_page"/>
</record>
<!-- Open website on install -->
<record id="action_website" model="ir.actions.act_url">
<field name="name">Website</field>
-9
View File
@@ -6,15 +6,6 @@
<field name="domain"></field>
</record>
<record id="menu_contactus2" model="website.menu">
<field name="name">Contact us</field>
<field name="url">/contactus</field>
<field name="parent_id" search="[('website_id', '=', ref('website2')), ('parent_id', '=', False)]"/>
<field name="sequence" type="int">60</field>
<field name="page_id" ref="contactus_page"/>
<field name="website_id" ref="website2"/>
</record>
<!-- BS Debug Page -->
<!-- Showcase all (most?) BS components and utilities -->
<record id="bs_debug_page" model="website.page">
+32 -15
View File
@@ -158,19 +158,27 @@ class Website(models.Model):
self.homepage_id = self.env['website.page'].search([('website_id', '=', self.id),
('key', '=', standard_homepage.key)])
top_menu = self.env['website.menu'].create({
'name': _('Top Menu for website %s') % self.id,
'website_id': self.id,
'sequence': 0
})
self.menu_id = top_menu.id
self.env['website.menu'].create({
'name': _('Home'),
'url': '/',
'website_id': self.id,
'parent_id': top_menu.id,
'sequence': 10
})
# Bootstrap default menu hierarchy, create a new minimalist one if no default
default_menu = self.env.ref('website.main_menu')
self.copy_menu_hierarchy(default_menu)
@api.model
def copy_menu_hierarchy(self, top_menu):
def copy_menu(menu, t_menu):
new_menu = menu.copy({
'parent_id': t_menu.id,
'website_id': self.id,
})
for submenu in menu.child_id:
copy_menu(submenu, new_menu)
for website in self:
new_top_menu = top_menu.copy({
'name': _('Top Menu for Website %s') % website.id,
'website_id': website.id,
})
for submenu in top_menu.child_id:
copy_menu(submenu, new_top_menu)
@api.model
def new_page(self, name=False, add_menu=False, template='website.default_page', ispage=True, namespace=None):
@@ -383,7 +391,6 @@ class Website(models.Model):
return dependencies
# ----------------------------------------------------------
# Languages
# ----------------------------------------------------------
@@ -1071,7 +1078,13 @@ class Menu(models.Model):
it for every website.
Note: Particulary useful when installing a module that adds a menu like
/shop. So every website has the shop menu.
Be careful to return correct record for ir.model.data xml_id in case
of default main menus creation.
'''
# Only used when creating website_data.xml default menu
if vals.get('url') == '/default-main-menu':
return super(Menu, self).create(vals)
if vals.get('website_id'):
return super(Menu, self).create(vals)
elif self._context.get('website_id'):
@@ -1080,10 +1093,14 @@ class Menu(models.Model):
else:
# create for every site
for website in self.env['website'].search([]):
vals.update({
w_vals = dict(vals, **{
'website_id': website.id,
'parent_id': website.menu_id.id,
})
res = super(Menu, self).create(w_vals)
# if creating a default menu, we should also save it as such
default_menu = self.env.ref('website.main_menu', raise_if_not_found=False)
if default_menu and vals.get('parent_id') == default_menu.id:
res = super(Menu, self).create(vals)
return res # Only one record is returned but multiple could have been created
+18 -8
View File
@@ -4,14 +4,6 @@ from odoo.tests import common
class TestMenu(common.TransactionCase):
def test_website_own_menu_container(self):
Website = self.env['website']
Menu = self.env['website.menu']
total_menus = Menu.search_count([])
Website.create({'name': 'new website'})
self.assertEqual(total_menus + 2, Menu.search_count([]), "New website's bootstraping should have created a container menu and home menu")
def test_menu_got_duplicated(self):
Menu = self.env['website.menu']
total_menu_items = Menu.search_count([])
@@ -49,3 +41,21 @@ class TestMenu(common.TransactionCase):
Menu.save(1, {'data': data, 'to_delete': []})
self.assertEqual(total_menu_items + 2, Menu.search_count([]), "Creating 2 new menus should create only 2 menus records")
def test_default_menu_for_new_website(self):
Website = self.env['website']
Menu = self.env['website.menu']
total_menu_items = Menu.search_count([])
# Simulating website.menu created on module install (blog, shop, forum..) that will be created on default menu tree
default_menu = self.env.ref('website.main_menu')
Menu.create({
'name': 'Sub Default Menu',
'parent_id': default_menu.id,
})
self.assertEqual(total_menu_items + 3, Menu.search_count([]), "Creating a default child menu should create it as such and copy it on every website")
# Ensure new website got a top menu
total_menus = Menu.search_count([])
Website.create({'name': 'new website'})
self.assertEqual(total_menus + 4, Menu.search_count([]), "New website's bootstraping should have duplicate default menu tree (Top/Home/Contactus/Sub Default Menu)")