[MOV] website, http_routing: compute language data in http_routing.ir_http instead of website

ir_http override in website manage languages through methods or attributes
directly defined on website model. Those methods are get_languages method
and default_lang_code attribute. In order to be able to have a translation
layer independent of website we have to have access to this data without
depending on website record.

This commit solves this by adding class methods on ir_http override
located in http_routing. Basic implementation comes directly from website
default methods _active_languages and _default_language. Website overrides
those methods in order to be based on website values defined through
language_ids and default_lang_id for available languages and default
language.

Website behavior is therefore untouched whereas http_routing implements
a basic default behavior. This commit updates ir_http code in website
to use those methods and ease next commits which will move parts of that
code.
This commit is contained in:
Thibault Delavallée
2017-08-08 14:24:59 +02:00
parent 014b5c9f7c
commit 3148925c43
5 changed files with 55 additions and 17 deletions
+20
View File
@@ -102,3 +102,23 @@ class ModelConverter(ModelConverter):
if not env[self.model].browse(record_id).exists():
record_id = abs(record_id)
return env[self.model].browse(record_id)
class IrHttp(models.AbstractModel):
_inherit = ['ir.http']
@classmethod
def _get_languages(cls):
return request.env['res.lang'].search([])
@classmethod
def _get_language_codes(cls):
languages = cls._get_languages()
return [(lang.code, lang.name) for lang in languages]
@classmethod
def _get_default_lang(cls):
lang_code = request.env['ir.values'].sudo().get_default('res.partner', 'lang')
if lang_code:
return request.env['res.lang'].search([('code', '=', lang_code)], limit=1)
return request.env['res.lang'].search([], limit=1)
+27 -9
View File
@@ -76,7 +76,7 @@ class Http(models.AbstractModel):
# Try to find a similar lang. Eg: fr_BE and fr_FR
short = lang.partition('_')[0]
short_match = False
for code, dummy in request.website.get_languages():
for code, dummy in cls._get_language_codes():
if code == lang:
return lang
if not short_match and code.startswith(short):
@@ -167,7 +167,7 @@ class Http(models.AbstractModel):
request.website = request.env['website'].get_current_website() # can use `request.env` since auth methods are called
context = dict(request.context)
context['website_id'] = request.website.id
langs = [lg[0] for lg in request.website.get_languages()]
langs = [lg[0] for lg in cls._get_language_codes()]
path = request.httprequest.path.split('/')
if first_pass:
is_a_bot = cls.is_a_bot()
@@ -175,20 +175,20 @@ class Http(models.AbstractModel):
url_lang = nearest_lang and path[1]
preferred_lang = ((cook_lang if cook_lang in langs else False)
or (not is_a_bot and cls.get_nearest_lang(request.lang))
or request.website.default_lang_code)
or cls._get_default_lang().code)
request.lang = 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)
if ((url_lang and (url_lang != request.lang or url_lang == cls._get_default_lang().code))
or (not url_lang and request.website_multilang and request.lang != cls._get_default_lang().code)
and request.httprequest.method != 'POST') \
and (not is_a_bot or (url_lang and url_lang == request.website.default_lang_code)):
and (not is_a_bot or (url_lang and url_lang == cls._get_default_lang().code)):
if url_lang:
path.pop(1)
if request.lang != request.website.default_lang_code:
if request.lang != cls._get_default_lang().code:
path.insert(1, request.lang)
path = '/'.join(path) or '/'
request.context = context
@@ -200,7 +200,7 @@ class Http(models.AbstractModel):
path.pop(1)
request.context = context
return cls.reroute('/'.join(path) or '/')
if request.lang == request.website.default_lang_code:
if request.lang == cls._get_default_lang().code:
context['edit_translations'] = False
if not context.get('tz'):
context['tz'] = request.session.get('geoip', {}).get('time_zone')
@@ -216,6 +216,24 @@ class Http(models.AbstractModel):
resp.set_cookie('website_lang', request.lang)
return resp
@classmethod
def _get_languages(cls):
if request.website:
return request.website.language_ids
return super(Http, cls)._get_languages()
@classmethod
def _get_language_codes(cls):
if request.website:
return request.website._get_languages()
return super(Http, cls)._get_language_codes()
@classmethod
def _get_default_lang(cls):
if request.website:
return request.website.default_lang_id
return super(Http, cls)._get_default_lang()
@classmethod
def reroute(cls, path):
if not hasattr(request, 'rerouting'):
@@ -246,7 +264,7 @@ class Http(models.AbstractModel):
generated_path = werkzeug.url_unquote_plus(path)
current_path = werkzeug.url_unquote_plus(request.httprequest.path)
if generated_path != current_path:
if request.lang != request.website.default_lang_code:
if request.lang != cls._get_default_lang().code:
path = '/' + request.lang + path
if request.httprequest.query_string:
path += '?' + request.httprequest.query_string
+3 -3
View File
@@ -110,7 +110,7 @@ class View(models.Model):
if request and getattr(request, 'website_enabled', False):
editable = request.website.is_publisher()
translatable = editable and self._context.get('lang') != request.website.default_lang_code
translatable = editable and self._context.get('lang') != request.env['ir.http']._get_default_lang().code
editable = not translatable and editable
if 'main_object' not in qcontext:
@@ -121,8 +121,8 @@ class View(models.Model):
website=request.website,
url_for=website.url_for,
res_company=request.website.company_id.sudo(),
default_lang_code=request.website.default_lang_code,
languages=request.website.get_languages(),
default_lang_code=request.env['ir.http']._get_default_lang().code,
languages=request.env['ir.http']._get_language_codes(),
translatable=translatable,
editable=editable,
menu_data=self.env['ir.ui.menu'].load_menus_root() if request.website.is_user() else None,
+4 -4
View File
@@ -43,7 +43,7 @@ def url_for(path_or_uri, lang=None):
location = urls.url_join(current_path, location)
lang = lang or request.context.get('lang')
langs = [lg[0] for lg in request.website.get_languages()]
langs = [lg[0] for lg in request.env['ir.http']._get_language_codes()]
if (len(langs) > 1 or force_lang) and is_multilang_url(location, langs):
ps = location.split('/')
@@ -52,10 +52,10 @@ def url_for(path_or_uri, lang=None):
if force_lang:
ps[1] = lang.encode('utf-8')
# Remove the default language unless it's explicitly provided
elif ps[1] == request.website.default_lang_code:
elif ps[1] == request.env['ir.http']._get_default_lang().code:
ps.pop(1)
# Insert the context language or the provided language
elif lang != request.website.default_lang_code or force_lang:
elif lang != request.env['ir.http']._get_default_lang().code or force_lang:
ps.insert(1, lang.encode('utf-8'))
location = '/'.join(ps)
@@ -64,7 +64,7 @@ def url_for(path_or_uri, lang=None):
def is_multilang_url(local_url, langs=None):
if not langs:
langs = [lg[0] for lg in request.website.get_languages()]
langs = [lg[0] for lg in request.env['ir.http']._get_language_codes()]
spath = local_url.split('/')
# if a language is already in the path, remove it
if spath[1] in langs:
+1 -1
View File
@@ -467,7 +467,7 @@ class IrActionsReport(models.Model):
if request and hasattr(request, 'website'):
if request.website is not None:
website = request.website
context = dict(context, translatable=context.get('lang') != request.website.default_lang_code)
context = dict(context, translatable=context.get('lang') != request.env['ir.http']._get_default_lang().code)
view_obj = self.env['ir.ui.view'].with_context(context)
values.update(