Merge pull request #2300 from odoo-dev/master-website-multi-sig

[MERGE] Domain name based multi website
This commit is contained in:
Fabien Meghazi
2014-09-16 16:33:40 +02:00
12 changed files with 189 additions and 57 deletions
+2 -2
View File
@@ -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/<website_xml_id>
url = "/page/" + re.sub(r"^website\.", '', xml_id)
+3
View 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">
+74
View File
@@ -132,5 +132,79 @@ 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" type="xml">
<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>
+3
View 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:
@@ -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):
+17 -2
View File
@@ -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'
+33 -32
View 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,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)
+1 -1
View 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">
+33
View File
@@ -78,6 +78,7 @@
<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>
<record id="menu_tree" model="ir.ui.view">
@@ -95,5 +96,37 @@
</field>
</record>
<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 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>
@@ -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>
-6
View 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)
+21 -14
View 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'),
@@ -312,7 +313,7 @@ class view(osv.osv):
if not values.get('name'):
values['name'] = "%s %s" % (values.get('model'), values['type'])
self.read_template.clear_cache(self)
self._read_template.clear_cache(self)
return super(view, self).create(
cr, uid,
self._compute_defaults(cr, uid, values, context=context),
@@ -335,7 +336,7 @@ class view(osv.osv):
if custom_view_ids:
self.pool.get('ir.ui.view.custom').unlink(cr, uid, custom_view_ids)
self.read_template.clear_cache(self)
self._read_template.clear_cache(self)
ret = super(view, self).write(
cr, uid, ids,
self._compute_defaults(cr, uid, vals, context=context),
@@ -896,18 +897,11 @@ class view(osv.osv):
#------------------------------------------------------
# QWeb template views
#------------------------------------------------------
read_template_cache = dict(accepted_keys=('lang','inherit_branding', 'editable', 'translatable'))
_read_template_cache = dict(accepted_keys=('lang','inherit_branding', 'editable', 'translatable'))
if config['dev_mode']:
read_template_cache['size'] = 0
@tools.ormcache_context(**read_template_cache)
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.pool['ir.model.data'].xmlid_to_res_id(cr, uid, xml_id, raise_if_not_found=True)
_read_template_cache['size'] = 0
@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)
@@ -920,8 +914,21 @@ class view(osv.osv):
arch = etree.tostring(root, encoding='utf-8', xml_declaration=True)
return arch
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)
@tools.ormcache(skiparg=3)
def get_view_id(self, cr, uid, xml_id, context=None):
return self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, xml_id, raise_if_not_found=True)
def clear_cache(self):
self.read_template.clear_cache(self)
self._read_template.clear_cache(self)
def _contains_branded(self, node):
return node.tag == 't'\
+1
View 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: