root vor 8 Jahren
Commit
8516a45e4f

+ 2 - 0
__init__.py

@@ -0,0 +1,2 @@
+import controllers
+import models

BIN
__init__.pyc


+ 25 - 0
__openerp__.py

@@ -0,0 +1,25 @@
+{
+    'name': 'Multi Website',
+    'category': 'Website',
+    'summary': 'Build Multiple Websites',
+    'website': 'https://www.odoo.com',
+    'version': '1.0',
+    'description': """
+OpenERP Multi Website
+=====================
+
+        """,
+    'author': 'OpenERP SA',
+    'depends': ['website'],
+    'installable': True,
+    'data': [
+        'data/data.xml',
+        'views/res_config.xml',
+        'views/website_views.xml',
+    ],
+    'demo' : [
+        'demo/website.xml',
+        'demo/template.xml',
+    ],
+    'application': True,
+}

+ 1 - 0
controllers/__init__.py

@@ -0,0 +1 @@
+import main

BIN
controllers/__init__.pyc


+ 114 - 0
controllers/main.py

@@ -0,0 +1,114 @@
+import re
+
+import werkzeug
+import openerp
+import datetime
+from itertools import islice
+from openerp.addons.web import http
+from openerp.http import request
+from openerp.addons.website.controllers.main import Website, SITEMAP_CACHE_TIME, LOC_PER_SITEMAP
+
+
+class website_multi(Website):
+
+    @http.route('/', type='http', auth="public", website=True)
+    def index(self, **kw):
+        cr, uid, context = request.cr, request.uid, request.context
+        page = 'homepage'
+        main_menu = request.website.menu_id
+        first_menu = main_menu.child_id and main_menu.child_id[0]
+        if first_menu:
+            if not (first_menu.url.startswith(('/page/', '/?', '/#')) or (first_menu.url == '/')):
+                return request.redirect(first_menu.url)
+            if first_menu.url.startswith('/page/'):
+                return request.registry['ir.http'].reroute(first_menu.url)
+        return self.page(page)
+
+    @http.route('/website/add/<path:path>', type='http', auth="user", website=True)
+    def pagenew(self, path, noredirect=False, add_menu=None):
+        cr, uid, context = request.cr, request.uid, request.context
+
+        xml_id = request.registry['website'].new_page(request.cr, request.uid, path, context=request.context)
+        if add_menu:
+            request.registry['website.menu'].create(cr, uid, {
+                'name': path,
+                'url': '/page/' + xml_id,
+                'parent_id': request.website.menu_id.id,
+                'website_id': request.website.id
+            }, context=context)
+
+        # Reverse action in order to allow shortcut for /page/<website_xml_id>
+        url = "/page/" + re.sub(r"^website\.", '', xml_id)
+
+        if noredirect:
+            return werkzeug.wrappers.Response(url, mimetype='text/plain')
+
+        return werkzeug.utils.redirect(url)
+
+    @http.route()
+    def sitemap_xml_index(self):
+        cr, uid, context = request.cr, openerp.SUPERUSER_ID, request.context
+        current_website = request.website
+        ira = request.registry['ir.attachment']
+        iuv = request.registry['ir.ui.view']
+        mimetype ='application/xml;charset=utf-8'
+        content = None
+
+        def create_sitemap(url, content):
+            ira.create(cr, uid, dict(
+                datas=content.encode('base64'),
+                mimetype=mimetype,
+                type='binary',
+                name=url,
+                url=url,
+            ), context=context)
+
+        dom = [('url', '=' , '/sitemap-%d.xml' % current_website.id), ('type', '=', 'binary')]
+        sitemap = ira.search_read(cr, uid, dom, ('datas', 'create_date'), limit=1, context=context)
+
+        if sitemap:
+            # Check if stored version is still valid
+            server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT
+            create_date = datetime.datetime.strptime(sitemap[0]['create_date'], server_format)
+            delta = datetime.datetime.now() - create_date
+            if delta < SITEMAP_CACHE_TIME:
+                content = sitemap[0]['datas'].decode('base64')
+
+        if not content:
+            # Remove all sitemaps in ir.attachments as we're going to regenerated them
+            dom = [('type', '=', 'binary'), '|', ('url', '=like' , '/sitemap-%d-%%.xml' % current_website.id),
+                   ('url', '=' , '/sitemap-%d.xml' % current_website.id)]
+            sitemap_ids = ira.search(cr, uid, dom, context=context)
+            if sitemap_ids:
+                ira.unlink(cr, uid, sitemap_ids, context=context)
+
+            pages = 0
+            first_page = None
+            locs = current_website.sudo(user=current_website.user_id.id).enumerate_pages()
+            while True:
+                values = {
+                    'locs': islice(locs, 0, LOC_PER_SITEMAP),
+                    'url_root': request.httprequest.url_root[:-1],
+                }
+                urls = iuv.render(cr, uid, 'website.sitemap_locs', values, context=context)
+                if urls.strip():
+                    page = iuv.render(cr, uid, 'website.sitemap_xml', dict(content=urls), context=context)
+                    if not first_page:
+                        first_page = page
+                    pages += 1
+                    create_sitemap('/sitemap-%d-%d.xml' % (current_website.id, pages), page)
+                else:
+                    break
+            if not pages:
+                return request.not_found()
+            elif pages == 1:
+                content = first_page
+            else:
+                # Sitemaps must be split in several smaller files with a sitemap index
+                content = iuv.render(cr, uid, 'website.sitemap_index_xml', dict(
+                    pages=range(1, pages + 1),
+                    url_root=request.httprequest.url_root,
+                ), context=context)
+            create_sitemap('/sitemap-%d.xml' % current_website.id, content)
+
+        return request.make_response(content, [('Content-Type', mimetype)])

BIN
controllers/main.pyc


+ 37 - 0
data/data.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="1">
+
+        <record id="website.default_website" model="website">
+            <field name="menu_id" ref="website.main_menu"/>
+        </record>
+
+        <record id="website.main_menu" model="website.menu">
+            <field name="website_id" ref='website.default_website'/>
+        </record>
+
+        <record id="website.menu_homepage" model="website.menu">
+            <field name="website_id" ref='website.default_website'/>
+        </record>
+
+        <record id="website.menu_contactus" model="website.menu">
+            <field name="website_id" ref='website.default_website'/>
+        </record>
+
+        <record id="website.homepage" model="ir.ui.view">
+            <field name="website_id" ref="website.default_website"/>
+            <field name="key">website.homepage</field>
+        </record>
+
+        <record id="website.contactus" model="ir.ui.view">
+            <field name="website_id" ref="website.default_website"/>
+            <field name="key">website.contactus</field>
+        </record>
+
+        <record id="website.aboutus" model="ir.ui.view">
+            <field name="website_id" ref="website.default_website"/>
+            <field name="key">website.aboutus</field>
+        </record>
+
+    </data>
+</openerp>

+ 224 - 0
demo/template.xml

@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+    	<!-- Different homepage for website 127.0.0.1 /!\ key should be the same as other homepage -->
+   	  	<record id="website_ip_homepage_template" model="ir.ui.view">
+           <field name="name">Homepage (127.0.0.1)</field>
+           <field name="type">qweb</field>
+           <field name="page" eval="True" />
+
+           <field name="website_id" ref="website_ip" />
+           <field name="key">website.homepage</field>
+
+           <field name="arch" type="xml">
+               <t name="Homepage" priority="29" t-name="website.homepage">
+				  <t t-call="website.layout">
+				    <div id="wrap" class="oe_structure oe_empty">
+				      <section class="oe_dark mt16 mb16">
+				        <div class="container">
+				          <div class="row">
+				            <div class="col-md-12 text-center mt32 mb32">
+				              <h2>Website 127.0.0.1 is so cool</h2>
+				            </div>
+				            <div class="col-md-12">
+				              <img class="img img-responsive" src="/website/static/src/img/big_picture.png" style="margin: 0 auto;"/>
+				            </div>
+				            <div class="col-md-6 col-md-offset-3 mb16 mt16">
+				              <p class="text-center">
+				                <b>A Small Subtitle</b>
+				              </p>
+				              <p class="text-center">Choose a vibrant image and write an inspiring paragraph about it. It does not have to be long, but it should reinforce your image.</p>
+				              <p class="text-center">
+				                <a href="/page/website.contactus">Contact us »</a>
+				              </p>
+				            </div>
+				          </div>
+				        </div>
+				      </section>
+				    </div>
+				  </t>
+				</t>
+           </field>
+        </record>
+        
+        
+        <!--new page for website 127.0.0.1 /!\ key should be the end of url specify in the menu -->
+        <!-- key should be equal to t-name -->
+        <record id="website_ip_other_template" model="ir.ui.view">
+           <field name="name">New page for 127.0.0.1</field>
+           <field name="type">qweb</field>
+           <field name="page" eval="True" />
+
+           <field name="website_id" ref="website_ip" />
+           <field name="key">website.other-127-0-0-1-page</field>
+
+           <field name="arch" type="xml">
+            <t t-name="website.other-127-0-0-1-page">
+				<t t-call="website.layout">
+					<div id="wrap" class="oe_structure oe_empty"/>
+					<div><h1>Other page on 127.0.0.1</h1></div>
+					<div id="wrap" class="oe_structure oe_empty"/>
+				</t>
+			</t>
+
+           </field>
+        </record>
+        
+        <!--Change Layout -->
+        <!-- Page should be False for layout template -->
+        <record id="website_ip_layout" model="ir.ui.view">
+           <field name="name">Main Layout for 127.0.0.1</field>
+           <field name="type">qweb</field>
+           
+           <field name="page" eval="False" />
+
+           <field name="website_id" ref="website_ip" />
+           <field name="key">website.layout</field>
+
+           <field name="arch" type="xml">
+            <t name="Main layout" t-name="website.layout">&lt;!DOCTYPE html&gt;
+			    <html t-att-lang="lang and lang.replace('_', '-')" t-att-data-website-id="website.id if editable and website else None" t-att-data-editable="'1' if editable else None" t-att-data-translatable="'1' if translatable else None" t-att-data-view-xmlid="xmlid if editable else None" t-att-data-main-object="repr(main_object) if editable else None" t-att-data-oe-company-name="res_company.name">
+			        <head>
+			            <meta charset="utf-8"/>
+			            <t t-if="main_object and 'website_meta_title' in main_object and not title">
+			                <t t-set="title" t-value="main_object.website_meta_title"/>
+			            </t>
+			            <t t-if="main_object and 'name' in main_object and not title and not additional_title">
+			                <t t-set="additional_title" t-value="main_object.name"/>
+			            </t>
+			            <t t-if="not title">
+			                <t t-set="title"><t t-if="additional_title"><t t-raw="additional_title"/> | </t><t t-esc="(website or res_company).name"/></t>
+			            </t>
+			
+			            <meta name="viewport" content="initial-scale=1"/>
+			            <meta name="description" t-att-content="main_object and 'website_meta_description' in main_object                 and main_object.website_meta_description or website_meta_description"/>
+			            <meta name="keywords" t-att-content="main_object and 'website_meta_keywords' in main_object                 and main_object.website_meta_keywords or website_meta_keywords"/>
+			            <title><t t-esc="title"/></title>
+			
+			            <t t-set="languages" t-value="website.get_languages() if website else None"/>
+			            <t t-if="request and request.website_multilang and website">
+			                <t t-foreach="website.get_alternate_languages(request.httprequest)" t-as="lang">
+			                    <link rel="alternate" t-att-hreflang="lang['hreflang']" t-att-href="lang['href']"/>
+			                </t>
+			            </t>
+			
+			            <t t-call-assets="web.assets_common" t-js="false"/>
+			            <t t-call-assets="website.assets_frontend" t-js="false"/>
+			
+			            <t t-raw="head or ''" name="layout_head"/>
+			        </head>
+			        <body>
+			            <div id="wrapwrap">
+			                <header>
+			                    <div class="navbar navbar-default navbar-static-top">
+			                        <div class="container">
+			                            <div class="navbar-header">
+			                                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-top-collapse">
+			                                    <span class="sr-only">Toggle navigation</span>
+			                                    <span class="icon-bar"/>
+			                                    <span class="icon-bar"/>
+			                                    <span class="icon-bar"/>
+			                                </button>
+			                                <a class="navbar-brand" href="/" t-field="res_company.name"/>
+			                            </div>
+			                            <div class="collapse navbar-collapse navbar-top-collapse">
+			                                <ul class="nav navbar-nav navbar-right" id="top_menu">
+			                                    <t t-foreach="website.menu_id.child_id" t-as="submenu">
+			                                        <t t-call="website.submenu"/>
+			                                    </t>
+			                                    <li class="divider" t-ignore="true" t-if="website.user_id != user_id"/>
+			                                    <li class="dropdown" t-ignore="true" t-if="website.user_id != user_id">
+			                                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+			                                            <b>
+			                                                <span t-esc="user_id.name"/>
+			                                                <span class="caret"/>
+			                                            </b>
+			                                        </a>
+			                                        <ul class="dropdown-menu js_usermenu" role="menu">
+			                                            <li><a href="/web" role="menuitem">My Account</a></li>
+			                                            <li class="divider"/>
+			                                            <li><a t-attf-href="/web/session/logout?redirect=/" role="menuitem">Logout</a></li>
+			                                        </ul>
+			                                    </li>
+			                                </ul>
+			                            </div>
+			                        </div>
+			                    </div>
+			                </header>
+			                <main>
+			                    <t t-raw="0"/>
+			                </main>
+			                <footer>
+			                    <div id="footer_container">
+			                    </div>
+			               		<div id="other_footer">
+			                    	<h2> New stuff under the footer</h2>
+			                    </div>
+			                </footer>
+			                
+			            </div>
+			
+			            <t t-call-assets="web.assets_common" t-css="false"/>
+			            <t t-call-assets="website.assets_frontend" t-css="false"/>
+			            <script t-if="website and website.google_analytics_key">
+			                (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+			                (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+			                m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+			                })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+			
+			                ga('create', _.str.trim('<t t-esc="website.google_analytics_key"/>'), 'auto');
+			                ga('send','pageview');
+			            </script>
+			        </body>
+			    </html>
+			</t>
+
+           </field>
+        </record>
+        
+       <!--Add footer, since we change the layout, we lost all the inherited view of the layout from localhost -->
+       <record id="website_ip_footer" model="ir.ui.view">
+           <field name="name">Main Layout for 127.0.0.1</field>
+           <field name="type">qweb</field>
+           
+           <field name="page" eval="False" />
+
+           <field name="website_id" ref="website_ip" />
+           <field name="key">website.footer</field>
+		   <field name="inherit_id" ref="website_ip_layout" />
+           <field name="arch" type="xml">
+           <data inherit_id="website.layout" name="Footer">
+			    <xpath expr="//div[@id='footer_container']" position="replace">
+			        <div class="oe_structure" id="footer">
+			            <section data-snippet-id="three-columns">
+			                <div class="container">
+			                    <div class="row">
+			                        <div class="col-md-4">
+			                            <h4 class="mt16">Subtitle</h4>
+			                            <p>
+			                                <a href="/">Homepage</a>
+			                            </p>
+			                        </div>
+			                        <div class="col-md-4">
+			                            <h4 class="mt16">Some Stuff for 127.0.0.1</h4>
+			                            <p>
+			                                ...
+			                            </p>
+			                        </div>
+			                        <div class="col-md-4">
+			                            <h4 class="mt16">Contact editor of 127.0.0.1</h4>
+			                            <p>
+			                                ...
+			                            </p>
+			                        </div>
+			                    </div>
+			                </div>
+			            </section>
+			        </div>
+			    </xpath>
+			</data>
+           </field>
+        </record>
+    </data>
+</openerp>
+    

+ 44 - 0
demo/website.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+		
+        <record id="public_user_website_ip" model="res.users">
+            <field name="name">Public User (127.0.0.1)</field>
+            <field name="login">Public User (127.0.0.1)</field>
+            <field name="active" eval="True" />
+            <field name="groups_id" eval="[(6,0,[ref('base.group_public'), ref('share.group_share_user')])]" />
+        </record>
+        
+        
+        <record id="website_ip" model="website">
+            <field name="name">127.0.0.1</field>
+            <field name="language_ids" eval="[(6,0,[ref('base.lang_en')])]" />
+            <field name="default_lang_id" ref="base.lang_en" />
+            <field name="user_id" ref="public_user_website_ip" />
+        </record>
+        
+        <record id="website_ip_top_menu" model="website.menu">
+            <field name="name">Top Menu (127.0.0.1)</field>
+            <field name="website_id" ref="website_ip" />
+            <field name="parent_id"></field>
+             <field name="url"></field>
+        </record>
+        
+        <record id="website_ip_homepage_menu" model="website.menu">
+            <field name="name">Homepage</field>
+            <field name="website_id" ref="website_ip" />
+            <field name="parent_id" ref="website_ip_top_menu" />
+             <field name="url">/page/homepage</field>
+        </record>
+        
+        <record id="website_ip_other_menu" model="website.menu">
+            <field name="name">Other page</field>
+            <field name="website_id" ref="website_ip" />
+            <field name="parent_id" ref="website_ip_top_menu" />
+        	<field name="url">/page/website.other-127-0-0-1-page</field>
+        </record>
+        
+
+
+    </data>
+</openerp>

+ 2 - 0
models/__init__.py

@@ -0,0 +1,2 @@
+import ir_ui_view
+import website

BIN
models/__init__.pyc


+ 124 - 0
models/ir_ui_view.py

@@ -0,0 +1,124 @@
+from lxml import etree
+
+from openerp import tools
+from openerp.osv import osv, fields, orm
+from openerp import SUPERUSER_ID
+
+
+class view(osv.osv):
+
+    _inherit = "ir.ui.view"
+
+    _columns = {
+        'website_id': fields.many2one('website', ondelete='cascade', string="Website", copy=False),
+        'key': fields.char('Key')
+    }
+
+    _sql_constraints = [(
+        'key_website_id_unique',
+        'unique(key, website_id)',
+        'Key must be unique per website.'
+    )]
+
+    def _view_obj(self, cr, uid, view_id, context=None):
+        if isinstance(view_id, basestring):
+            try:
+                return self.pool['ir.model.data'].xmlid_to_object(
+                    cr, uid, view_id, raise_if_not_found=True, context=context
+                )
+            except:
+                # Try to fallback on key instead of xml_id
+                if self.search(cr, uid, [('key', '=', view_id),('website_id','=',context.get('website_id', False))], context=context):
+                    rec_id = self.search(cr, uid, [('key', '=', view_id),('website_id','=',context.get('website_id', False))], context=context)
+                else:
+                    rec_id = self.search(cr, uid, [('key', '=', view_id)], context=context)
+                if rec_id:
+                    return self.browse(cr, uid, rec_id, context=context)[0]
+                else:
+                    raise
+        elif isinstance(view_id, (int, long)):
+            return self.browse(cr, uid, view_id, context=context)
+
+        # assume it's already a view object (WTF?)
+        return view_id
+
+    @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_ids = self.search(cr, uid, domain, order='website_id', limit=1, context=context)
+            if not xml_ids:
+                xml_id = self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, xml_id, raise_if_not_found=True)
+                if self.read(cr, uid, xml_id, ['page'], context=context)['page']:
+                    raise ValueError('Invalid template id: %r' % (xml_id,))
+            else:
+                xml_id = xml_ids[0]
+        else:
+            xml_id = self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, xml_id, raise_if_not_found=True)
+        return xml_id
+
+    _read_template_cache = dict(accepted_keys=('lang', 'inherit_branding', 'editable', 'translatable', 'website_id'))
+
+    @tools.ormcache_context(**_read_template_cache)
+    def _read_template(self, cr, uid, view_id, context=None):
+        arch = self.read_combined(cr, uid, view_id, fields=['arch'], context=context)['arch']
+        arch_tree = etree.fromstring(arch)
+
+        if 'lang' in context:
+            arch_tree = self.translate_qweb(cr, uid, view_id, arch_tree, context['lang'], context)
+
+        self.distribute_branding(arch_tree)
+        root = etree.Element('templates')
+        root.append(arch_tree)
+        arch = etree.tostring(root, encoding='utf-8', xml_declaration=True)
+        return arch
+
+    @tools.ormcache(size=0)
+    def read_template(self, cr, uid, xml_id, context=None):
+        if isinstance(xml_id, (int, long)):
+            view_id = xml_id
+        else:
+            if '.' not in xml_id:
+                raise ValueError('Invalid template id: %r' % (xml_id,))
+            view_id = self.get_view_id(cr, uid, xml_id, context=context)
+        return self._read_template(cr, uid, view_id, context=context)
+
+    def clear_cache(self):
+        self._read_template.clear_cache(self)
+        self.get_view_id.clear_cache(self)
+        
+    def get_inheriting_views_arch(self, cr, uid, view_id, model, context=None):
+        arch = super(view, self).get_inheriting_views_arch(cr, uid, view_id, model, context=context)
+        if not context or not 'website_id' in context:
+            return arch
+        
+        view_ids = [v for _, v in arch]
+        view_arch_to_add_per_key = {}
+        keep_view_ids = []
+        for view_rec in self.browse(cr, SUPERUSER_ID, view_ids, context):
+            #case 1: there is no key, always keep the view
+            if not view_rec.key:
+                keep_view_ids.append(view_rec.id)
+                
+            #case 2: Correct website
+            elif view_rec.website_id and view_rec.website_id.id == context['website_id']:
+                view_arch_to_add_per_key[view_rec.key] = (view_rec.website_id.id, view_rec.id)
+            #case 3: no website add it if no website
+            if not view_rec.website_id:
+                view_web_id, view_id = view_arch_to_add_per_key.get(view_rec.key, (False, False))
+                if not view_web_id:
+                    view_arch_to_add_per_key[view_rec.key] = (False, view_rec.id)
+                #else: do nothing, you already have the right view
+            #case 4: website is wrong: do nothing
+        #Put all the view_id we keep together
+        keep_view_ids.extend([view_id for _, view_id in view_arch_to_add_per_key.values()])
+        return [(arch, view_id) for arch, view_id  in arch if view_id in keep_view_ids]
+      
+      
+
+            

BIN
models/ir_ui_view.pyc


+ 142 - 0
models/website.py

@@ -0,0 +1,142 @@
+import openerp
+from openerp import SUPERUSER_ID
+from openerp.osv import orm, fields, osv
+from openerp.addons.website.models.website import slugify
+from openerp.addons.web.http import request
+from werkzeug.exceptions import NotFound
+import werkzeug
+
+class website(orm.Model):
+
+    _inherit = "website"
+
+    def _get_menu_website(self, cr, uid, ids, context=None):
+        res = []
+        for menu in self.pool.get('website.menu').browse(cr, uid, ids, context=context):
+            if menu.website_id:
+                res.append(menu.website_id.id)
+        # IF a menu is changed, update all websites
+        return res
+
+    def _get_menu(self, cr, uid, ids, name, arg, context=None):
+        result = {}
+        menu_obj = self.pool['website.menu']
+
+        for website_id in ids:
+            menu_ids = menu_obj.search(cr, uid, [
+                ('parent_id', '=', False),
+                ('website_id', '=', website_id),
+            ], order='id', context=context)
+            result[website_id] = menu_ids and menu_ids[0] or False
+
+        return result
+
+    _columns = {
+        '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)
+            }
+        )
+    }
+
+    _defaults = {
+        'user_id': lambda s, c, u, x: s.pool['ir.model.data'].xmlid_to_res_id(c, SUPERUSER_ID, 'base.public_user'),
+        'company_id': lambda s, c, u, x: s.pool['ir.model.data'].xmlid_to_res_id(c, SUPERUSER_ID, 'base.main_company'),
+    }
+
+    def new_page(self, cr, uid, name, template='website.default_page', ispage=True, context=None):
+        context = context or {}
+        imd = self.pool['ir.model.data']
+        view = self.pool['ir.ui.view']
+        template_module, template_name = template.split('.')
+
+        # completely arbitrary max_length
+        page_name = slugify(name, max_length=50)
+        page_xmlid = "%s.%s" % (template_module, page_name)
+
+        try:
+            # existing page
+            imd.get_object_reference(cr, uid, template_module, page_name)
+        except ValueError:
+            # new page
+            _, template_id = imd.get_object_reference(cr, uid, template_module, template_name)
+
+            page_id = view.copy(cr, uid, template_id, {
+                'website_id': context.get('website_id'),
+                'key': page_xmlid
+            }, 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,
+            })
+
+        return page_xmlid
+
+    @openerp.tools.ormcache(skiparg=4)
+    def _get_current_website_id(self, cr, uid, domain_name, context=None):
+        ids = self.search(cr, uid, [('name', '=', domain_name)], context=context)
+        return ids and ids[0] or None
+
+    def get_current_website(self, cr, uid, context=None):
+        domain_name = request.httprequest.environ.get('HTTP_HOST', '').split(':')[0]
+        website_id = self._get_current_website_id(cr, uid, domain_name, context=context)
+        request.context['website_id'] = website_id or 1
+        return self.browse(cr, uid, website_id or 1, context=context)
+
+    def get_template(self, cr, uid, ids, template, context=None):
+        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)
+
+
+class ir_http(osv.AbstractModel):
+    _inherit = 'ir.http'
+
+    def _auth_method_public(self):
+        if not request.session.uid:
+            domain_name = request.httprequest.environ.get('HTTP_HOST', '').split(':')[0]
+            website_id = self.pool['website']._get_current_website_id(request.cr, openerp.SUPERUSER_ID, domain_name, context=request.context)
+            if website_id:
+                request.uid = self.pool['website'].browse(request.cr, openerp.SUPERUSER_ID, website_id, request.context).user_id.id
+            else:
+                dummy, request.uid = self.pool['ir.model.data'].get_object_reference(request.cr, openerp.SUPERUSER_ID, 'base', 'public_user')
+        else:
+            request.uid = request.session.uid
+
+    def _get_converters(self):
+        converters = super(ir_http, self)._get_converters()
+        converters['page'] = PageMultiWebsiteConverter
+        return converters
+
+
+class PageMultiWebsiteConverter(werkzeug.routing.PathConverter):
+    def generate(self, cr, uid, query=None, args={}, context=None):
+        View = request.registry['ir.ui.view']
+        dom = [('page', '=', True), '|', ('website_id', '=', request.website.id), ('website_id', '=', False)]
+        views = View.search_read(cr, uid, dom, fields=['key', 'xml_id', 'priority','write_date'], order='name', context=context)
+
+        for view in views:
+            key = view['key'] or view['xml_id'] or ''
+            xid = key.startswith('website.') and key[8:] or key
+
+            if xid=='homepage': continue
+            if query and query.lower() not in xid.lower(): continue
+            record = {'loc': xid}
+            if view['priority'] != 16:
+                record['__priority'] = min(round(view['priority'] / 32.0, 1), 1)
+            if view['write_date']:
+                record['__lastmod'] = view['write_date'][:10]
+            yield record
+

BIN
models/website.pyc


+ 17 - 0
views/res_config.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <record id="view_website_config_setting_website_multi" model="ir.ui.view">
+            <field name="name">Website Multi Settings</field>
+            <field name="model">website.config.settings</field>
+            <field name="inherit_id" ref="website.view_website_config_settings" />
+            <field name="arch" type="xml">
+                <xpath expr="//field[@name='website_id']" position="attributes">
+                    <attribute name="invisible">0</attribute>
+                </xpath>
+            </field>
+        </record>
+
+    </data>
+</openerp>

+ 97 - 0
views/website_views.xml

@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <!-- website -->
+
+        <record id="view_website_form_website_multi" model="ir.ui.view">
+            <field name="name">website.form</field>
+            <field name="model">website</field>
+            <field name="inherit_id" ref="website.view_website_form"/>
+            <field name="arch" type="xml">
+                <xpath expr="//form" position="attributes">
+                    <attribute name="version">7.0</attribute>
+                </xpath>
+                <xpath expr="//header" position="replace"></xpath>
+                <xpath expr="//field[@name='name']" position="after">
+                    <field name="menu_id"/>
+                    <field name="user_id" context="{ 'active_test' : False }" />
+                </xpath>
+                <xpath expr="//field[@name='default_lang_id']" position="attributes">
+                	<attribute name="required">True</attribute>
+                </xpath>
+                <xpath expr="//div[@name='other']" position="after">
+                    <div name="menu">
+                        <separator string="Menu"/>
+                        <group name="Menu">
+                            <button type="action" name="%(website.action_website_menu)d" string="Configure website menus" class="oe_link"/>
+                        </group>
+                    </div>
+                </xpath>
+            </field>
+        </record>
+
+        <record id="action_websites_configuration" model="ir.actions.act_window">
+            <field name="name">Websites Settings</field>
+            <field name="res_model">website</field>
+            <field name="view_mode">tree,form</field>
+            <field name="target">current</field>
+        </record>
+
+        <record id="website.menu_website_configuration" model="ir.ui.menu">
+            <field name="name">Websites Settings</field>
+            <field name="action" ref="website_multi.action_websites_configuration"/>
+        </record>
+
+        <!-- ir.ui.view -->
+
+        <record id="view_view_form_website_multi" model="ir.ui.view">
+            <field name="model">ir.ui.view</field>
+            <field name="inherit_id" ref="base.view_view_form"/>
+            <field name="arch" type="xml">
+                <xpath expr="//field[@name='name']" position="after">
+                    <field name="website_id"/>
+                    <field name="key"/>
+                </xpath>
+            </field>
+        </record>
+
+        <!-- website.menu -->
+
+        <record id="menu_search" model="ir.ui.view">
+            <field name="name">website.menu.search</field>
+            <field name="model">website.menu</field>
+            <field name="arch" type="xml">
+                <search string="Search Menus">
+                    <field name="name"/>
+                    <field name="url"/>
+                    <!-- <field name="website_id"/> -->
+                    <group string="Group By">
+                        <filter string="name" domain="[]" context="{'group_by': 'name'}"/>
+                        <filter string="url" domain="[]" context="{'group_by': 'url'}"/>
+                        <!-- <filter string="website" name="my_websites" domain="[]" context="{'group_by': 'website_id'}"/> -->
+                    </group>
+                </search>
+            </field>
+        </record>
+
+        <record id="menu_tree_website_multi" model="ir.ui.view">
+            <field name="name">Website Multi Website Menu Tree</field>
+            <field name="model">website.menu</field>
+            <field name="inherit_id" ref="website.menu_tree"/>
+            <field name="arch" type="xml">
+                <xpath expr="//field[@name='name']" position="before">
+                    <field name="website_id"/>
+                </xpath>
+            </field>
+        </record>
+
+        <record id="action_website_menu" model="ir.actions.act_window">
+            <field name="name">Website Menu</field>
+            <field name="res_model">website.menu</field>
+            <field name="view_mode">list</field>
+            <!-- <field name="context">{'search_default_my_websites': 1}</field> -->
+        </record>
+
+    </data>
+</openerp>