From 5f258c831ec37f7a78f8d41d2024b6381e4ba651 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Wed, 27 Aug 2014 10:58:42 +0200 Subject: [PATCH 01/10] [WIP] Multi website --- addons/website/controllers/main.py | 6 +- addons/website/data/data.xml | 3 + addons/website/data/demo.xml | 76 +++++++++++++++++++ addons/website/models/ir_http.py | 1 + addons/website/models/ir_ui_view.py | 8 +- addons/website/models/website.py | 44 ++++++----- addons/website/views/res_config.xml | 2 +- addons/website/views/website_views.xml | 14 ++++ .../website_blog/data/website_blog_data.xml | 1 + addons/website_event/controllers/main.py | 6 -- openerp/addons/base/ir/ir_qweb.py | 6 ++ openerp/addons/base/ir/ir_ui_view.py | 1 + openerp/tools/convert.py | 3 + 13 files changed, 142 insertions(+), 29 deletions(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index c8bb06e7438..63465d6ad88 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -164,11 +164,13 @@ class Website(openerp.addons.web.controllers.main.Home): def pagenew(self, path, noredirect=False, add_menu=None): xml_id = request.registry['website'].new_page(request.cr, request.uid, path, context=request.context) if add_menu: - model, id = request.registry["ir.model.data"].get_object_reference(request.cr, request.uid, 'website', 'main_menu') + current = request.website + new_menu_id = current.menu_id.id request.registry['website.menu'].create(request.cr, request.uid, { 'name': path, 'url': "/page/" + xml_id, - 'parent_id': id, + 'parent_id': new_menu_id, + 'website_id': current.id, }, context=request.context) # Reverse action in order to allow shortcut for /page/ url = "/page/" + re.sub(r"^website\.", '', xml_id) diff --git a/addons/website/data/data.xml b/addons/website/data/data.xml index f83b1378f54..1c1567a310c 100644 --- a/addons/website/data/data.xml +++ b/addons/website/data/data.xml @@ -11,6 +11,7 @@ Top Menu + @@ -18,6 +19,7 @@ /page/homepage 10 + @@ -25,6 +27,7 @@ /page/website.contactus 60 + diff --git a/addons/website/data/demo.xml b/addons/website/data/demo.xml index 55feac2bd5d..6463ea92845 100644 --- a/addons/website/data/demo.xml +++ b/addons/website/data/demo.xml @@ -132,5 +132,81 @@ response = request.render("website.template_partner_comment", values) code ir.actions.server + + + 0.0.0.0 + https://twitter.com/odooapps + https://www.facebook.com/Odoo + https://plus.google.com/+Odooapps + http://www.linkedin.com/company/odoo + + + + + + Homepage + qweb + website.homepage + + + + +
+ +
+
+ + ]]> +
+
+ + + Top Menu + + + + + Home + /page/homepage + + 10 + + + + + Contact us + /page/website.contactus + + 60 + + + diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index e78c92acab7..7baa5eac3f6 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -88,6 +88,7 @@ class ir_http(orm.AbstractModel): request.redirect = lambda url, code=302: werkzeug.utils.redirect(url_for(url), code) request.website = request.registry['website'].get_current_website(request.cr, request.uid, context=request.context) + request.context['website_id'] = request.website.id langs = [lg[0] for lg in request.website.get_languages()] path = request.httprequest.path.split('/') if first_pass: diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index 2c468e37af8..dbacf0cd9ed 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -16,13 +16,19 @@ class view(osv.osv): 'website_meta_description': fields.text("Website meta description", size=160, translate=True), 'website_meta_keywords': fields.char("Website meta keywords", translate=True), 'customize_show': fields.boolean("Show As Optional Inherit"), + 'website_id': fields.many2one('website',ondelete='cascade', string="Website"), } + + _sql_constraints = [ + ('key_website_id_uniq', 'unique(key, website_id)', + 'Key must be unique per website.'), + ] + _defaults = { 'page': False, 'customize_show': False, } - def _view_obj(self, cr, uid, view_id, context=None): if isinstance(view_id, basestring): return self.pool['ir.model.data'].xmlid_to_object( diff --git a/addons/website/models/website.py b/addons/website/models/website.py index a1414f204bc..1a0eaf45a60 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -29,6 +29,7 @@ from openerp.tools import html_escape as escape from openerp.tools import ustr as ustr from openerp.tools.safe_eval import safe_eval from openerp.addons.web.http import request +from werkzeug.exceptions import NotFound logger = logging.getLogger(__name__) @@ -137,15 +138,13 @@ def urlplus(url, params): return werkzeug.Href(url)(params or None) class website(osv.osv): - def _get_menu_website(self, cr, uid, ids, context=None): - # IF a menu is changed, update all websites - return self.search(cr, uid, [], context=context) - def _get_menu(self, cr, uid, ids, name, arg, context=None): - root_domain = [('parent_id', '=', False)] - menus = self.pool.get('website.menu').search(cr, uid, root_domain, order='id', context=context) - menu = menus and menus[0] or False - return dict( map(lambda x: (x, menu), ids) ) + res = {} + menu_obj = self.pool.get('website.menu') + for id in ids: + menu_ids = menu_obj.search(cr, uid, [('parent_id', '=', False), ('website_id', '=', id)], order='id', context=context) + res[id] = menu_ids and menu_ids[0] or False + return res _name = "website" # Avoid website.website convention for conciseness (for new api). Got a special authorization from xmo and rco _description = "Website" @@ -164,14 +163,12 @@ class website(osv.osv): 'google_analytics_key': fields.char('Google Analytics Key'), 'user_id': fields.many2one('res.users', string='Public User'), 'partner_id': fields.related('user_id','partner_id', type='many2one', relation='res.partner', string='Public Partner'), - 'menu_id': fields.function(_get_menu, relation='website.menu', type='many2one', string='Main Menu', - store= { - 'website.menu': (_get_menu_website, ['sequence','parent_id','website_id'], 10) - }) + 'menu_id': fields.function(_get_menu, relation='website.menu', type='many2one', string='Main Menu') } - _defaults = { - 'company_id': lambda self,cr,uid,c: self.pool['ir.model.data'].xmlid_to_res_id(cr, openerp.SUPERUSER_ID, 'base.public_user'), + 'user_id': lambda self,cr,uid,c: self.pool['ir.model.data'].xmlid_to_res_id(cr, openerp.SUPERUSER_ID, 'base.public_user'), + 'company_id': lambda self,cr,uid,c: self.pool['ir.model.data'].xmlid_to_res_id(cr, openerp.SUPERUSER_ID,'base.main_company'), + } # cf. Wizard hack in website_views.xml @@ -198,7 +195,9 @@ class website(osv.osv): except ValueError: # new page _, template_id = imd.get_object_reference(cr, uid, template_module, template_name) - page_id = view.copy(cr, uid, template_id, context=context) + website_id = context.get('website_id') + key = template_module+'.'+page_name + page_id = view.copy(cr, uid, template_id, {'website_id': website_id, 'key': key}, context=context) page = view.browse(cr, uid, page_id, context=context) page.write({ 'arch': page.arch.replace(template, page_xmlid), @@ -210,7 +209,7 @@ class website(osv.osv): 'module': template_module, 'model': 'ir.ui.view', 'res_id': page_id, - 'noupdate': True + 'noupdate': True, }, context=context) return page_xmlid @@ -260,8 +259,10 @@ class website(osv.osv): return langs def get_current_website(self, cr, uid, context=None): - # TODO: Select website, currently hard coded - return self.pool['website'].browse(cr, uid, 1, context=context) + domain_name=request.httprequest.host.split(":")[0].lower() + ids=self.search(cr, uid, [('name', '=', domain_name)], context=context) + website = self.browse(cr, uid, ids and ids[0] or 1, context=context) + return website def is_publisher(self, cr, uid, ids, context=None): Access = self.pool['ir.model.access'] @@ -275,11 +276,16 @@ class website(osv.osv): def get_template(self, cr, uid, ids, template, context=None): if isinstance(template, (int, long)): view_id = template + else: if '.' not in template: template = 'website.%s' % template module, xmlid = template.split('.', 1) - model, view_id = request.registry["ir.model.data"].get_object_reference(cr, uid, module, xmlid) + key = template + website_id=request.context.get('website_id') + view_id=self.pool["ir.ui.view"].search(cr, uid, [('key', '=', key),'|',('website_id','=',website_id),('website_id','=',False)], order='website_id', limit=1, context=context) + if not view_id: + raise NotFound return self.pool["ir.ui.view"].browse(cr, uid, view_id, context=context) def _render(self, cr, uid, ids, template, values=None, context=None): diff --git a/addons/website/views/res_config.xml b/addons/website/views/res_config.xml index b9b6810a070..81d8cf6c9d7 100644 --- a/addons/website/views/res_config.xml +++ b/addons/website/views/res_config.xml @@ -13,7 +13,7 @@