diff options
| author | fja-odoo <fja@odoo.com> | 2020-08-12 15:07:13 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2020-08-14 17:40:58 +0000 |
| commit | 704bcc552709f3b1e024f4a7aa83743f982fd5df (patch) | |
| tree | 52da8928ede4572cb0a37626d27f5a8685f5ce93 | |
| parent | 0b2f2b5d9632d49a384834885ef7d76b79320bd7 (diff) | |
[IMP] portal, *: move language switcher to portal
*: base, http_routing, website
Make the language switcher available on portal without website
installed.
Part of https://github.com/odoo/odoo/pull/55300
task-2203383
Co-authored-by: Jeremy Kersten <jke@odoo.com>
Co-authored-by: qsm-odoo <qsm@odoo.com>
| -rw-r--r-- | addons/http_routing/models/ir_http.py | 7 | ||||
| -rw-r--r-- | addons/portal/models/__init__.py | 1 | ||||
| -rw-r--r-- | addons/portal/models/ir_http.py | 7 | ||||
| -rw-r--r-- | addons/portal/models/ir_ui_view.py | 26 | ||||
| -rw-r--r-- | addons/portal/static/src/scss/portal.scss | 16 | ||||
| -rw-r--r-- | addons/portal/views/portal_templates.xml | 26 | ||||
| -rw-r--r-- | addons/website/models/ir_http.py | 2 | ||||
| -rw-r--r-- | addons/website/models/ir_ui_view.py | 4 | ||||
| -rw-r--r-- | addons/website/models/res_lang.py | 8 | ||||
| -rw-r--r-- | addons/website/static/src/scss/website.scss | 16 | ||||
| -rw-r--r-- | addons/website/views/website_templates.xml | 32 | ||||
| -rw-r--r-- | odoo/addons/base/models/res_lang.py | 11 | ||||
| -rw-r--r-- | odoo/addons/base/wizard/base_language_install.py | 2 |
13 files changed, 102 insertions, 56 deletions
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 @@ </div> </div> </xpath> + <xpath expr="//*[hasclass('o_footer_copyright_name')]" position="after"> + <t t-call="portal.language_selector"/> + </xpath> + </template> + + <template id="language_selector" name="Language Selector"> + <t t-set="language_selector_visible" t-value="len(languages) > 1"/> + <ul class="js_language_selector mb0 list-inline" t-if="language_selector_visible"> + <li class="list-inline-item"> + <div class="dropup"> + <button class="btn btn-sm btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> + <span t-esc="list(filter(lambda lg : lg[0] == lang, languages))[0][2].split('/').pop()"/> + <span class="caret ml4"/> + </button> + <div class="dropdown-menu" role="menu"> + <t t-foreach="languages" t-as="lg"> + <a t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang_code=lg[0])" + class="dropdown-item js_change_lang" + t-att-data-url_code="lg[1]"> + <t t-esc="lg[2].split('/').pop()"/> + </a> + </t> + </div> + </div> + </li> + </ul> </template> <template id="portal_breadcrumbs" name="Portal Breadcrumbs"> 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 @@ <!-- Background now controlled by css configuration, using color combinations --> <attribute name="class" add="o_colored_level o_cc" separator=" "/> </xpath> - <xpath expr="//div[hasclass('o_footer_copyright')]//span[hasclass('o_footer_copyright_name')]" position="after"> - <t t-call="website.language_selector"/> - </xpath> <xpath expr="//t[@t-call='web.brand_promotion']/.." position="attributes"> <attribute name="class" add="o_not_editable" separator=" "/> <attribute name="t-if">not editable</attribute> @@ -594,25 +591,14 @@ </xpath> </template> -<template id="language_selector" name="Language Selector"> - <ul class="js_language_selector mb0 list-inline" t-if="(request and request.is_frontend_multilang and len(languages) > 1) or (website and (editable or translatable))"> - <li class="list-inline-item"> - <div class="dropup"> - <button class="btn btn-sm btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> - <span t-esc="list(filter(lambda lg : lg[0] == lang, languages))[0][2].split('/').pop()"/> - <span class="caret ml4"/> - </button> - <div class="dropdown-menu" role="menu"> - <t t-foreach="languages" t-as="lg"> - <a t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang_code=lg[0])" - class="dropdown-item js_change_lang" - t-att-data-url_code="lg[1]"> - <t t-esc="lg[2].split('/').pop()"/> - </a> - </t> - </div> - </div> - </li> +<template id="language_selector" inherit_id="portal.language_selector"> + <!-- Always show the language selector on editable websites --> + <xpath expr="//t[@t-set='language_selector_visible']" position="after"> + <t t-set="language_selector_visible" t-value="language_selector_visible or (website and (editable or translatable))"/> + </xpath> + + <!-- Add the button to add a language --> + <xpath expr="//ul/li" position="after"> <li groups="website.group_website_publisher" class="list-inline-item"> <t t-set="url_return" t-value="quote_plus(url_for('', '[lang]') + '?' + keep_query())"/> <a class="d-none d-sm-block" t-attf-href="/web#action=base.action_view_base_language_install&website_id=#{website.id if website else ''}&url_return=#{url_return}"> @@ -620,7 +606,7 @@ Add a language... </a> </li> - </ul> + </xpath> </template> <template id="record_cover"> 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) |
