diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index c8bb06e74384fea5f004729013afb04ceeffca9c..63465d6ad888c7ce902335e9c7fdb0c07f7f07d4 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/<website_xml_id> url = "/page/" + re.sub(r"^website\.", '', xml_id) diff --git a/addons/website/data/data.xml b/addons/website/data/data.xml index f83b1378f5477fd73c4ed3a6c5f54851544cdb47..1c1567a310c758d6238f9c7e701ebb1e4eb0c023 100644 --- a/addons/website/data/data.xml +++ b/addons/website/data/data.xml @@ -11,6 +11,7 @@ <record id="main_menu" model="website.menu"> <field name="name">Top Menu</field> + <field name="website_id" ref="default_website"/> </record> <record id="menu_homepage" model="website.menu"> @@ -18,6 +19,7 @@ <field name="url">/page/homepage</field> <field name="parent_id" ref="website.main_menu"/> <field name="sequence" type="int">10</field> + <field name="website_id" ref="default_website"/> </record> <record id="menu_contactus" model="website.menu"> @@ -25,6 +27,7 @@ <field name="url">/page/website.contactus</field> <field name="parent_id" ref="website.main_menu"/> <field name="sequence" type="int">60</field> + <field name="website_id" ref="default_website"/> </record> <record id="base.group_website_publisher" model="res.groups"> diff --git a/addons/website/data/demo.xml b/addons/website/data/demo.xml index 55feac2bd5daaaf241cf628f41b79e72ab83b2c7..6463ea928454a1c18a02d4a05275c2ac31e285c3 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) <field name="state">code</field> <field name="type">ir.actions.server</field> </record> + + <record id="website2" model="website"> + <field name="name">0.0.0.0</field> + <field name="social_twitter">https://twitter.com/odooapps</field> + <field name="social_facebook">https://www.facebook.com/Odoo</field> + <field name="social_googleplus">https://plus.google.com/+Odooapps</field> + <field name="social_linkedin">http://www.linkedin.com/company/odoo</field> + <field name="language_ids" eval="[(6, 0, [ ref('base.lang_en')])]"/> + <field name="default_lang_id" ref="base.lang_en"/> + </record> + + <record id="website2_homepage" model="ir.ui.view"> + <field name="name">Homepage</field> + <field name="type">qweb</field> + <field name="key">website.homepage</field> + <field name="website_id" ref="website2"/> + <field name="arch"> + <![CDATA[ + <t name="Homepage" priority="29" t-name="website.homepage"> + <t t-call="website.layout"> + <div id="wrap" class="oe_structure oe_empty"> + <div class="carousel slide mb32" id="myCarousel0" style="height: 320px;"> + <ol class="carousel-indicators hidden"> + <li class="active" data-slide-to="0" data-target="#myCarousel0"/> + </ol> + <div class="carousel-inner"> + <div class="item image_text oe_img_bg active" style="background-image: url(http://0.0.0.0:8069/website/static/src/img/banner/mountains.jpg);"> + <div class="container"> + <div class="row content"> + <div class="carousel-content col-md-6 col-sm-12"> + <h2>Homepage 0.0.0.0</h2> + <h3>Click to customize this text</h3> + <p> + <a class="btn btn-success btn-large" href="/page/website.contactus">Contact us</a> + </p> + </div> + <span class="carousel-img col-md-6 hidden-sm hidden-xs"> </span> + </div> + </div> + </div> + </div> + <div class="carousel-control left hidden" data-slide="prev" data-target="#myCarousel0" href="#myCarousel0" style="width: 10%"> + <i class="fa fa-chevron-left"/> + </div> + <div class="carousel-control right hidden" data-slide="next" data-target="#myCarousel0" href="#myCarousel0" style="width: 10%"> + <i class="fa fa-chevron-right"/> + </div> + </div> + </div> + </t> + </t> + ]]> + </field> + </record> + + <record id="website2_main_menu" model="website.menu"> + <field name="name">Top Menu</field> + <field name="website_id" ref="website2"/> + </record> + + <record id="website2_menu_homepage" model="website.menu"> + <field name="name">Home</field> + <field name="url">/page/homepage</field> + <field name="parent_id" ref="website.website2_main_menu"/> + <field name="sequence" type="int">10</field> + <field name="website_id" ref="website2"/> + </record> + + <record id="website2_menu_contactus" model="website.menu"> + <field name="name">Contact us</field> + <field name="url">/page/website.contactus</field> + <field name="parent_id" ref="website.website2_main_menu"/> + <field name="sequence" type="int">60</field> + <field name="website_id" ref="website2"/> + </record> + </data> </openerp> diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index e78c92acab7e592a4b99dc421046fc7815aa2be4..7baa5eac3f689b84e0550af709a66d91a596ade4 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 2c468e37af826e5b41ce1f15b31a0ecf44773307..dbacf0cd9ed81e2e606eb38b6aa1861154b5ab1b 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 a1414f204bc4d4df473e7eb8fb08a9c3074d68c1..1a0eaf45a6046689342bce5e7433d924568d86aa 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 b9b6810a07053e232f0f69229f97cac7cff6f5e0..81d8cf6c9d722d3acbd3e4e8496ed1fa19efd533 100644 --- a/addons/website/views/res_config.xml +++ b/addons/website/views/res_config.xml @@ -13,7 +13,7 @@ <button string="Cancel" type="object" name="cancel" class="oe_link"/> </header> <div> - <field name="website_id" invisible="True" on_change="on_change_website_id(website_id)"/> + <field name="website_id" on_change="on_change_website_id(website_id)"/> <group string="Domain"> <label for="google_analytics_key"/> <div name="google_analytics_key"> diff --git a/addons/website/views/website_views.xml b/addons/website/views/website_views.xml index 06b982ede407cbb20e8055faadb9c85e602ec497..f1563792fa2917951efa9eddba6e6b1cdc0170aa 100644 --- a/addons/website/views/website_views.xml +++ b/addons/website/views/website_views.xml @@ -95,5 +95,19 @@ </field> </record> + <record model="ir.ui.view" id="view_view_form_extend"> + <field name="model">ir.ui.view</field> + + <field name="inherit_id" ref="base.view_view_form"/> + <field name="arch" type="xml"> + + <field name="name" position="after"> + <field name="website_id"/> + <field name="key"/> + </field> + + </field> + </record> + </data> </openerp> diff --git a/addons/website_blog/data/website_blog_data.xml b/addons/website_blog/data/website_blog_data.xml index 03f3c13127d14cd982e71d34ec6279f0ec19ac97..bd5478ac5f32b830185c51cd40973c0c906425e4 100644 --- a/addons/website_blog/data/website_blog_data.xml +++ b/addons/website_blog/data/website_blog_data.xml @@ -12,6 +12,7 @@ <field name="url" eval="'/blog/'+str(ref('website_blog.blog_blog_1'))"/> <field name="parent_id" ref="website.main_menu"/> <field name="sequence" type="int">40</field> + <field name="website_id" ref="website.default_website"/> </record> </data> diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index eac3c3e0a77973f1fe07fc04a4b8c0ecb1365219..6d0a0dfa74b34f29bc5efb576aeead0e9c8cdf44 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -179,12 +179,6 @@ class website_event(http.Controller): if '.' not in page: page = 'website_event.%s' % page - try: - request.website.get_template(page) - except ValueError, e: - # page not found - raise NotFound - return request.website.render(page, values) @http.route(['/event/<model("event.event"):event>'], type='http', auth="public", website=True) diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py index 5236e04dd8416631a8ad6d01d6304a44d1b7df10..220f8bf36c0bc3fbe9ea2677fde730e820e68fa7 100644 --- a/openerp/addons/base/ir/ir_qweb.py +++ b/openerp/addons/base/ir/ir_qweb.py @@ -237,6 +237,12 @@ class QWeb(orm.AbstractModel): if not isinstance(qwebcontext, QWebContext): qwebcontext = QWebContext(cr, uid, qwebcontext, loader=loader, context=context) + context = context or qwebcontext.context + website_id=context.get('website_id') + if website_id: + id_or_xml_id=self.pool["ir.ui.view"].search(cr, uid, [('key', '=', id_or_xml_id),'|',('website_id','=',website_id),('website_id','=',False)], order='website_id', limit=1, context=context)[0] + + qwebcontext['__template__'] = id_or_xml_id stack = qwebcontext.get('__stack__', []) if stack: diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index ef001cd303bce66c49e1044f1c2dbfafba407351..8f1f2e7dafdfba3074678cfe387d7f1a7fa6aea9 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -179,6 +179,7 @@ class view(osv.osv): _columns = { 'name': fields.char('View Name', required=True), 'model': fields.char('Object', select=True), + 'key': fields.char(string='Key'), 'priority': fields.integer('Sequence', required=True), 'type': fields.selection([ ('tree','Tree'), diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index c441cfdd6e12b65c3ebbfa52df99168f18212389..acb61f1d06d717f577451fa6ffd52afe0934007a 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -804,6 +804,7 @@ form: module.record_id""" % (xml_id,) record = etree.Element('record', attrib=record_attrs) record.append(Field(name, name='name')) + record.append(Field(full_tpl_id, name='key')) record.append(Field("qweb", name='type')) record.append(Field(el.get('priority', "16"), name='priority')) if 'inherit_id' in el.attrib: @@ -812,6 +813,8 @@ form: module.record_id""" % (xml_id,) record.append(Field(name='active', eval=el.get('active'))) if el.get('customize_show') in ("True", "False"): record.append(Field(name='customize_show', eval=el.get('customize_show'))) + if 'website_id' in el.attrib: + record.append(Field(name='website_id', ref=el.get('website_id'))) groups = el.attrib.pop('groups', None) if groups: grp_lst = map(lambda x: "ref('%s')" % x, groups.split(','))