[FIX] website: ir_http - no redirect for bot and save lang in cookie
Detect most of bots/crawlers to avoid auto redirect. Most bots fetch with lang en_US, so even if default website lang was not in en_US, googlebot was redirected to en_US page. Now we keep also the language selected by user into a cookie. If cookie exists but lang not in url, we redirect the user into his preferred language. Manage special case to allow to change the lang in url to set the default lang at fly in url and set the cookie... Many routes are not specified as multilang=False but should be. With the auto redirection, we need to update these routes to avoid useless redirects !
This commit is contained in:
parent
b10180887e
commit
a696913364
|
@ -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/<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/<page: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);
|
||||
</script>""" % (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]
|
||||
|
|
|
@ -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'):
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -323,9 +323,14 @@
|
|||
</div>
|
||||
<ul class="list-inline js_language_selector mt16" t-if="(request.website_multilang and len(languages) > 1) or editable">
|
||||
<li t-foreach="languages" t-as="lg">
|
||||
<a t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang=lg[0])"
|
||||
t-att-data-default-lang="editable and 'true' if lg[0] == website.default_lang_code else None">
|
||||
<t t-esc="lg[1].split('/').pop()"/></a>
|
||||
<a
|
||||
t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang=lg[0])"
|
||||
t-att-data-default-lang="editable and 'true' if lg[0] == website.default_lang_code else None"
|
||||
t-att-data-lang="lg[0]"
|
||||
class="js_change_lang"
|
||||
>
|
||||
<t t-esc="lg[1].split('/').pop()"/>
|
||||
</a>
|
||||
</li>
|
||||
<li groups="base.group_website_publisher">
|
||||
<t t-set="url_return" t-value="url_for('', '[lang]') + '?' + keep_query()"/>
|
||||
|
|
Loading…
Reference in New Issue