diff --git a/addons/http_routing/models/ir_http.py b/addons/http_routing/models/ir_http.py
index aa072912b31..6da75e3ef61 100644
--- a/addons/http_routing/models/ir_http.py
+++ b/addons/http_routing/models/ir_http.py
@@ -147,7 +147,7 @@ def url_lang(path_or_uri, lang_code=None):
# relative URL with either a path or a force_lang
if not url.netloc and not url.scheme and (url.path or force_lang):
location = werkzeug.urls.url_join(request.httprequest.path, location)
- lang_url_codes = [url_code for _, url_code, _ in Lang.get_available()]
+ lang_url_codes = [url_code for _, url_code, *_ in Lang.get_available()]
lang_code = pycompat.to_text(lang_code or request.context['lang'])
lang_url_code = Lang._lang_code_to_urlcode(lang_code)
lang_url_code = lang_url_code if lang_url_code in lang_url_codes else lang_code
@@ -208,7 +208,7 @@ def is_multilang_url(local_url, lang_url_codes=None):
2. If not matching 1., everything not under /static/ will be translatable
'''
if not lang_url_codes:
- lang_url_codes = [url_code for _, url_code, _ in request.env['res.lang'].get_available()]
+ lang_url_codes = [url_code for _, url_code, *_ in request.env['res.lang'].get_available()]
spath = local_url.split('/')
# if a language is already in the path, remove it
if spath[1] in lang_url_codes:
@@ -388,8 +388,7 @@ class IrHttp(models.AbstractModel):
path = request.httprequest.path.split('/')
is_a_bot = cls.is_a_bot()
- available_langs = Lang.get_available()
- lang_codes = [code for code, _, _ in available_langs]
+ lang_codes = [code for code, *_ in Lang.get_available()]
nearest_lang = not func and cls.get_nearest_lang(Lang._lang_get_code(path[1]))
cook_lang = request.httprequest.cookies.get('frontend_lang')
cook_lang = cook_lang in lang_codes and cook_lang
diff --git a/addons/portal/models/__init__.py b/addons/portal/models/__init__.py
index c9f2b8d412c..1c70d12386a 100644
--- a/addons/portal/models/__init__.py
+++ b/addons/portal/models/__init__.py
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import ir_http
+from . import ir_ui_view
from . import mail_thread
from . import mail_message
from . import portal_mixin
diff --git a/addons/portal/models/ir_http.py b/addons/portal/models/ir_http.py
index 3fad96ff9f1..9320f6d4f82 100644
--- a/addons/portal/models/ir_http.py
+++ b/addons/portal/models/ir_http.py
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
+from odoo.http import request
class IrHttp(models.AbstractModel):
@@ -11,3 +12,9 @@ class IrHttp(models.AbstractModel):
def _get_translation_frontend_modules_name(cls):
mods = super(IrHttp, cls)._get_translation_frontend_modules_name()
return mods + ['portal']
+
+ @classmethod
+ def _get_frontend_langs(cls):
+ if request and request.is_frontend:
+ return [lang[0] for lang in filter(lambda l: l[3], request.env['res.lang'].get_available())]
+ return super()._get_frontend_langs()
diff --git a/addons/portal/models/ir_ui_view.py b/addons/portal/models/ir_ui_view.py
new file mode 100644
index 00000000000..e51261170aa
--- /dev/null
+++ b/addons/portal/models/ir_ui_view.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, models
+from odoo.http import request
+from odoo.addons.http_routing.models.ir_http import url_for
+
+
+class View(models.Model):
+ _inherit = "ir.ui.view"
+
+ @api.model
+ def _prepare_qcontext(self):
+ """ Returns the qcontext : rendering context with portal specific value (required
+ to render portal layout template)
+ """
+ qcontext = super(View, self)._prepare_qcontext()
+ if request and getattr(request, 'is_frontend', False):
+ Lang = request.env['res.lang']
+ portal_lang_code = request.env['ir.http']._get_frontend_langs()
+ qcontext.update(dict(
+ self._context.copy(),
+ languages=[lang for lang in Lang.get_available() if lang[0] in portal_lang_code],
+ url_for=url_for,
+ ))
+ return qcontext
diff --git a/addons/portal/static/src/scss/portal.scss b/addons/portal/static/src/scss/portal.scss
index cdaccb9117c..604c0a70a25 100644
--- a/addons/portal/static/src/scss/portal.scss
+++ b/addons/portal/static/src/scss/portal.scss
@@ -535,3 +535,19 @@ form label {
}
}
}
+
+// Copyright
+.o_footer_copyright {
+
+ .js_language_selector {
+ display: inline-block;
+ }
+ @include media-breakpoint-up(md) {
+ .row {
+ display: flex;
+ > div {
+ margin: auto 0;
+ }
+ }
+ }
+}
diff --git a/addons/portal/views/portal_templates.xml b/addons/portal/views/portal_templates.xml
index 195a7c5a7cb..7cbfe33844f 100644
--- a/addons/portal/views/portal_templates.xml
+++ b/addons/portal/views/portal_templates.xml
@@ -40,6 +40,32 @@
+
+
+
+
+
+
+
+
diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py
index a3fa817754a..d29d367e5c2 100644
--- a/addons/website/models/ir_http.py
+++ b/addons/website/models/ir_http.py
@@ -216,7 +216,7 @@ class Http(models.AbstractModel):
@classmethod
def _get_frontend_langs(cls):
if get_request_website():
- return [code for code, _, _ in request.env['res.lang'].get_available()]
+ return [code for code, *_ in request.env['res.lang'].get_available()]
else:
return super()._get_frontend_langs()
diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py
index e62b25f7399..c7169067cbb 100644
--- a/addons/website/models/ir_ui_view.py
+++ b/addons/website/models/ir_ui_view.py
@@ -9,7 +9,6 @@ import werkzeug
from odoo import api, fields, models
from odoo import tools
from odoo.addons import website
-from odoo.addons.http_routing.models.ir_http import url_for
from odoo.exceptions import AccessError
from odoo.osv import expression
from odoo.http import request
@@ -431,13 +430,10 @@ class View(models.Model):
]
qcontext.update(dict(
- self._context.copy(),
main_object=self,
website=request.website,
is_view_active=request.website.is_view_active,
- url_for=url_for,
res_company=request.website.company_id.sudo(),
- languages=request.env['res.lang'].get_available(),
translatable=translatable,
editable=editable,
))
diff --git a/addons/website/models/res_lang.py b/addons/website/models/res_lang.py
index 9fc3f69e998..3c8ee9dcb52 100644
--- a/addons/website/models/res_lang.py
+++ b/addons/website/models/res_lang.py
@@ -19,8 +19,8 @@ class Lang(models.Model):
@api.model
@tools.ormcache_context(keys=("website_id",))
def get_available(self):
- """ Return the available languages as a list of (code, name) sorted by name. """
website = ir_http.get_request_website()
- if website:
- return sorted([(lang.code, lang.url_code, lang.name) for lang in request.website.language_ids])
- return super(Lang, self).get_available()
+ if not website:
+ return super().get_available()
+ # Return the website-available ones in this case
+ return request.website.language_ids.get_sorted()
diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss
index 99f5fd9eef0..088ebb12b0e 100644
--- a/addons/website/static/src/scss/website.scss
+++ b/addons/website/static/src/scss/website.scss
@@ -864,22 +864,6 @@ header {
}
}
-// Copyright
-.o_footer_copyright {
-
- .js_language_selector {
- display: inline-block;
- }
- @include media-breakpoint-up(md) {
- .row {
- display: flex;
- > div {
- margin: auto 0;
- }
- }
- }
-}
-
// Figure with special style
.o_figure_relative_layout {
position: relative;
diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml
index c74d73835ae..2d18621957f 100644
--- a/addons/website/views/website_templates.xml
+++ b/addons/website/views/website_templates.xml
@@ -156,9 +156,6 @@
-
-
-
not editable
@@ -594,25 +591,14 @@
-
-
+
diff --git a/odoo/addons/base/models/res_lang.py b/odoo/addons/base/models/res_lang.py
index dcf901e1a22..f3f54eb3e96 100644
--- a/odoo/addons/base/models/res_lang.py
+++ b/odoo/addons/base/models/res_lang.py
@@ -209,9 +209,14 @@ class Lang(models.Model):
@api.model
@tools.ormcache()
def get_available(self):
- """ Return the available languages as a list of (code, name) sorted by name. """
+ """ Return the available languages as a list of (code, url_code, name,
+ active) sorted by name.
+ """
langs = self.with_context(active_test=False).search([])
- return sorted([(lang.code, lang.url_code, lang.name) for lang in langs], key=itemgetter(2))
+ return langs.get_sorted()
+
+ def get_sorted(self):
+ return sorted([(lang.code, lang.url_code, lang.name, lang.active) for lang in self], key=itemgetter(2))
@tools.ormcache('self.id')
def _get_cached_values(self):
@@ -229,7 +234,7 @@ class Lang(models.Model):
@api.model
@tools.ormcache('code')
def _lang_code_to_urlcode(self, code):
- for c, urlc, name in self.get_available():
+ for c, urlc, name, *_ in self.get_available():
if c == code:
return urlc
return self._lang_get(code).url_code
diff --git a/odoo/addons/base/wizard/base_language_install.py b/odoo/addons/base/wizard/base_language_install.py
index f9f495c56f8..0d4fd9bc233 100644
--- a/odoo/addons/base/wizard/base_language_install.py
+++ b/odoo/addons/base/wizard/base_language_install.py
@@ -20,7 +20,7 @@ class BaseLanguageInstall(models.TransientModel):
@api.model
def _get_languages(self):
- return [[code, name] for code, _, name in self.env['res.lang'].get_available()]
+ return [[code, name] for code, _, name, *_ in self.env['res.lang'].get_available()]
lang = fields.Selection(_get_languages, string='Language', required=True,
default=_default_language)