diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index c8bb06e7438..5e3cc68a53b 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -164,11 +164,11 @@ 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') request.registry['website.menu'].create(request.cr, request.uid, { 'name': path, 'url': "/page/" + xml_id, - 'parent_id': id, + 'parent_id': request.website.menu_id.id, + 'website_id': request.website.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..e72c05dc933 100644 --- a/addons/website/data/demo.xml +++ b/addons/website/data/demo.xml @@ -132,5 +132,79 @@ 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..bc7b2c91560 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: @@ -122,6 +123,8 @@ class ir_http(orm.AbstractModel): # to url without language so google doesn't see duplicate content return request.redirect(path + '?' + request.httprequest.query_string, code=301) return self.reroute(path) + # bind modified context + request.website = request.website.with_context(request.context) return super(ir_http, self)._dispatch() def reroute(self, path): diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index 2c468e37af8..02dd2f3d351 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -3,7 +3,7 @@ import copy from lxml import etree, html -from openerp import SUPERUSER_ID +from openerp import SUPERUSER_ID, tools from openerp.addons.website.models import website from openerp.http import request from openerp.osv import osv, fields @@ -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( @@ -133,6 +139,15 @@ class view(osv.osv): return arch + @tools.ormcache_context(accepted_keys=('website_id',)) + def get_view_id(self, cr, uid, xml_id, context=None): + if context and 'website_id' in context and not isinstance(xml_id, (int, long)): + domain = [('key', '=', xml_id), '|', ('website_id', '=', context['website_id']), ('website_id', '=', False)] + [xml_id] = self.search(cr, uid, domain, order='website_id', limit=1, context=context) + else: + xml_id = super(view, self).get_view_id(cr, uid, xml_id, context=context) + return xml_id + def render(self, cr, uid, id_or_xml_id, values=None, engine='ir.qweb', context=None): if request and getattr(request, 'website_enabled', False): engine='website.qweb' diff --git a/addons/website/models/website.py b/addons/website/models/website.py index a1414f204bc..b2d1bb67d6d 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,20 +195,15 @@ 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), 'name': page_name, 'page': ispage, }) - imd.create(cr, uid, { - 'name': page_name, - 'module': template_module, - 'model': 'ir.ui.view', - 'res_id': page_id, - 'noupdate': True - }, context=context) return page_xmlid def page_for_name(self, cr, uid, ids, name, module='website', context=None): @@ -259,9 +251,19 @@ class website(osv.osv): lang['hreflang'] = lang['short'] return langs + @openerp.tools.ormcache(skiparg=4) + def _get_current_website_id(self, cr, uid, domain_name, context=None): + website_id = 1 + if request: + ids = self.search(cr, uid, [('name', '=', domain_name)], context=context) + if ids: + website_id = ids[0] + return website_id + 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.environ.get('HTTP_HOST', '').split(':')[0] + website_id = self._get_current_website_id(cr, uid, domain_name, context=context) + return self.browse(cr, uid, website_id, context=context) def is_publisher(self, cr, uid, ids, context=None): Access = self.pool['ir.model.access'] @@ -273,14 +275,13 @@ class website(osv.osv): return Access.check(cr, uid, 'ir.ui.menu', 'read', False, context=context) 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) - return self.pool["ir.ui.view"].browse(cr, uid, view_id, context=context) + if not isinstance(template, (int, long)) and '.' not in template: + template = 'website.%s' % template + View = self.pool['ir.ui.view'] + view_id = View.get_view_id(cr, uid, template, context=context) + if not view_id: + raise NotFound + return View.browse(cr, uid, view_id, context=context) def _render(self, cr, uid, ids, template, values=None, context=None): # TODO: remove this. (just kept for backward api compatibility for saas-3) 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 @@