diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 0fd0bd30ebf..f1f4f6d9992 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -51,6 +51,12 @@ class Website(openerp.addons.web.controllers.main.Home): # TODO: can't we just put auth=public, ... in web client ? return super(Website, self).web_login(*args, **kw) + @http.route('/website/lang/', type='http', auth="public", website=True, multilang=False) + def change_lang(self, lang, r, **kwargs): + redirect = werkzeug.utils.redirect(r or '/%s' % lang, 303) + redirect.set_cookie('website_lang', lang) + return redirect + @http.route('/page/', type='http', auth="public", website=True) def page(self, page, **opt): values = { @@ -232,14 +238,14 @@ class Website(openerp.addons.web.controllers.main.Home): request.cr, request.uid, xml_id, full=full, context=request.context) - @http.route('/website/get_view_translations', type='json', auth='public', website=True) + @http.route('/website/get_view_translations', type='json', auth='public', website=True, multilang=False) def get_view_translations(self, xml_id, lang=None): lang = lang or request.context.get('lang') return request.registry["ir.ui.view"].get_view_translations( request.cr, request.uid, xml_id, lang=lang, context=request.context) - @http.route('/website/set_translations', type='json', auth='public', website=True) + @http.route('/website/set_translations', type='json', auth='public', website=True, multilang=False) def set_translations(self, data, lang): irt = request.registry.get('ir.translation') for view_id, trans in data.items(): @@ -277,7 +283,7 @@ class Website(openerp.addons.web.controllers.main.Home): irt.create(request.cr, request.uid, new_trans) return True - @http.route('/website/translations', type='json', auth="public", website=True) + @http.route('/website/translations', type='json', auth="public", website=True, multilang=False) def get_website_translations(self, lang): module_obj = request.registry['ir.module.module'] module_ids = module_obj.search(request.cr, request.uid, [('name', 'ilike', 'website'), ('state', '=', 'installed')], context=request.context) @@ -293,7 +299,7 @@ class Website(openerp.addons.web.controllers.main.Home): website_url = url name = url.split("/").pop() attachment_id = Attachments.create(request.cr, request.uid, { - 'name':name, + 'name': name, 'type': 'url', 'url': url, 'res_model': 'ir.ui.view', @@ -330,7 +336,7 @@ class Website(openerp.addons.web.controllers.main.Home): window.parent['%s'](%s, %s); """ % (func, json.dumps(website_url), json.dumps(message)) - @http.route(['/website/publish'], type='json', auth="public", website=True) + @http.route(['/website/publish'], type='json', auth="public", website=True, multilang=False) def publish(self, id, object): _id = int(id) _object = request.registry[object] diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index c45a203f4da..3f1ec566a2f 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -42,6 +42,16 @@ class ir_http(orm.AbstractModel): else: request.uid = request.session.uid + bots = "bot|crawl|slurp|spider|curl|wget".split("|") + def is_a_bot(self): + # We don't use regexp and ustr voluntarily + # timeit has been done to check the optimum method + ua = request.httprequest.environ.get('HTTP_USER_AGENT', '').lower() + try: + return any(bot in ua for bot in self.bots) + except UnicodeDecodeError: + return any(bot in ua.encode('ascii', 'ignore') for bot in self.bots) + def _dispatch(self): first_pass = not hasattr(request, 'website') request.website = None @@ -75,6 +85,7 @@ class ir_http(orm.AbstractModel): record = self.geo_ip_resolver.record_by_addr(request.httprequest.remote_addr) or {} request.session['geoip'] = record + cook_lang = request.httprequest.cookies.get('website_lang') if request.website_enabled: try: if func: @@ -88,10 +99,13 @@ class ir_http(orm.AbstractModel): request.website = request.registry['website'].get_current_website(request.cr, request.uid, context=request.context) langs = [lg[0] for lg in request.website.get_languages()] path = request.httprequest.path.split('/') + if first_pass: if request.website_multilang: + is_a_bot = self.is_a_bot() # If the url doesn't contains the lang and that it's the first connection, we to retreive the user preference if it exists. - if not path[1] in langs and not request.httprequest.cookies.get('session_id'): + if not path[1] in langs and not is_a_bot: + request.lang = cook_lang or request.lang if request.lang not in langs: # Try to find a similar lang. Eg: fr_BE and fr_FR short = request.lang.split('_')[0] @@ -100,14 +114,16 @@ class ir_http(orm.AbstractModel): request.lang = langs_withshort[0] else: request.lang = request.website.default_lang_code - # We redirect with the right language in url - if request.lang != request.website.default_lang_code: - path.insert(1, request.lang) - path = '/'.join(path) or '/' - return request.redirect(path + '?' + request.httprequest.query_string) else: request.lang = request.website.default_lang_code + if request.lang != request.website.default_lang_code: + path.insert(1, request.lang) + path = '/'.join(path) or '/' + redirect = request.redirect(path + '?' + request.httprequest.query_string) + redirect.set_cookie('website_lang', request.lang) + return redirect + request.context['lang'] = request.lang if not func: if path[1] in langs: @@ -116,11 +132,17 @@ class ir_http(orm.AbstractModel): if request.lang == request.website.default_lang_code: # If language is in the url and it is the default language, redirect # to url without language so google doesn't see duplicate content - return request.redirect(path + '?' + request.httprequest.query_string, code=301) + resp = request.redirect(path + '?' + request.httprequest.query_string, code=301) + if cook_lang != request.lang: # If default lang setted in url directly + resp.set_cookie('website_lang', request.lang) + return resp return self.reroute(path) # bind modified context request.website = request.website.with_context(request.context) - return super(ir_http, self)._dispatch() + resp = super(ir_http, self)._dispatch() + if not cook_lang: + resp.set_cookie('website_lang', request.lang) + return resp def reroute(self, path): if not hasattr(request, 'rerouting'): diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index e464a4e7697..6364550778a 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -350,6 +350,19 @@ }); }); + $(document).on('click', '.js_change_lang', function(e) { + e.preventDefault(); + + var self = $(this); + // retrieve the hash before the redirect + var redirect = { + lang: self.data('lang'), + url: self.attr('href'), + hash: location.hash + }; + location.href = _.str.sprintf("/website/lang/%(lang)s?r=%(url)s%(hash)s", redirect); + }) + /* ----- KANBAN WEBSITE ---- */ $('.js_kanban').each(function () { website.init_kanban(this); diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 3beda6a4d77..450687511f5 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -323,9 +323,14 @@