From aea358ca67f88fa3fb13ac2766c5195223551d10 Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Tue, 28 Apr 2015 12:23:58 +0200 Subject: [PATCH] [FIX] website: ir_http - auto redirect for lang, use cookies to save pref language Save in cookie the last lang selected to allow to stay consistent at the next visit from visitor --- addons/website/models/ir_http.py | 70 ++++++++++++++++---------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index e19edb60b2f..b3b344415f6 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -52,6 +52,17 @@ class ir_http(orm.AbstractModel): except UnicodeDecodeError: return any(bot in ua.encode('ascii', 'ignore') for bot in self.bots) + def get_nearest_lang(self, lang): + # Try to find a similar lang. Eg: fr_BE and fr_FR + if lang in request.website.get_languages(): + return lang + + short = lang.split('_')[0] + for code, name in request.website.get_languages(): + if code.startswith(short): + return code + return False + def _dispatch(self): first_pass = not hasattr(request, 'website') request.website = None @@ -102,48 +113,39 @@ 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 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] - langs_withshort = [lg[0] for lg in request.website.get_languages() if lg[0].startswith(short)] - if len(langs_withshort): - request.lang = langs_withshort[0] - else: - request.lang = request.website.default_lang_code - else: - request.lang = request.website.default_lang_code + url_lang = not func and path[1] + nearest_lang = url_lang and self.get_nearest_lang(path[1]) + preferred_lang = ((cook_lang if cook_lang in langs else False) + or self.get_nearest_lang(request.lang) + or request.website.default_lang_code) + is_a_bot = self.is_a_bot() + + request.lang = request.context['lang'] = nearest_lang or preferred_lang + # if lang in url but not the displayed or default language --> change or remove + # or no lang in url, and lang to dispay not the default language --> add lang + # and not a POST request + # and not a bot or bot but default lang in url + if ((url_lang and (url_lang != request.lang or url_lang == request.website.default_lang_code)) + or (not url_lang and request.website_multilang and request.lang != request.website.default_lang_code) + and request.httprequest.method != 'POST') \ + and (not is_a_bot or (url_lang and url_lang == request.website.default_lang_code)): + if url_lang: + path.pop(1) 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: - request.lang = request.context['lang'] = path.pop(1) path = '/'.join(path) or '/' - 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 - 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) + redirect = request.redirect(path + '?' + request.httprequest.query_string) + redirect.set_cookie('website_lang', request.lang) + return redirect + elif url_lang: + path.pop(1) + return self.reroute('/'.join(path) or '/') # bind modified context request.website = request.website.with_context(request.context) resp = super(ir_http, self)._dispatch() - if not cook_lang: + if request.website_enabled and cook_lang != request.lang and hasattr(resp, 'set_cookie'): resp.set_cookie('website_lang', request.lang) return resp