[WIP] Multi website
authorGoffin Simon <simon.goffin@outlook.com>
Wed, 27 Aug 2014 08:58:42 +0000 (10:58 +0200)
committerFabien Meghazi <fme@openerp.com>
Tue, 16 Sep 2014 12:11:08 +0000 (14:11 +0200)
13 files changed:
addons/website/controllers/main.py
addons/website/data/data.xml
addons/website/data/demo.xml
addons/website/models/ir_http.py
addons/website/models/ir_ui_view.py
addons/website/models/website.py
addons/website/views/res_config.xml
addons/website/views/website_views.xml
addons/website_blog/data/website_blog_data.xml
addons/website_event/controllers/main.py
openerp/addons/base/ir/ir_qweb.py
openerp/addons/base/ir/ir_ui_view.py
openerp/tools/convert.py

index c8bb06e..63465d6 100644 (file)
@@ -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)
index f83b137..1c1567a 100644 (file)
@@ -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">
index 55feac2..6463ea9 100644 (file)
@@ -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>
index e78c92a..7baa5ea 100644 (file)
@@ -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:
index 2c468e3..dbacf0c 100644 (file)
@@ -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(
index a1414f2..1a0eaf4 100644 (file)
@@ -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):
index b9b6810..81d8cf6 100644 (file)
@@ -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">
index 06b982e..f156379 100644 (file)
             </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>
index 03f3c13..bd5478a 100644 (file)
@@ -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>
 
index eac3c3e..6d0a0df 100644 (file)
@@ -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)
index 5236e04..220f8bf 100644 (file)
@@ -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:
index ef001cd..8f1f2e7 100644 (file)
@@ -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'),
index c441cfd..acb61f1 100644 (file)
@@ -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(','))