From 326b54b7e0474164941021878560babaaf34f1de Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 21 Dec 2023 12:11:30 -0500 Subject: [PATCH] Closes #14579: Add user language preference --- netbox/account/views.py | 13 +++++++++++-- netbox/netbox/preferences.py | 19 ++++++++++++++----- netbox/netbox/settings.py | 9 +++++++++ netbox/users/forms/model_forms.py | 1 + 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/netbox/account/views.py b/netbox/account/views.py index 3156b2102..3dbba9b29 100644 --- a/netbox/account/views.py +++ b/netbox/account/views.py @@ -13,6 +13,7 @@ from django.shortcuts import render, resolve_url from django.urls import reverse from django.utils.decorators import method_decorator from django.utils.http import url_has_allowed_host_and_scheme, urlencode +from django.utils.translation import gettext_lazy as _ from django.views.decorators.debug import sensitive_post_parameters from django.views.generic import View from social_core.backends.utils import load_backends @@ -193,8 +194,16 @@ class UserConfigView(LoginRequiredMixin, View): if form.is_valid(): form.save() - messages.success(request, "Your preferences have been updated.") - return redirect('account:preferences') + messages.success(request, _("Your preferences have been updated.")) + response = redirect('account:preferences') + + # Set/clear language cookie + if language := form.cleaned_data['locale.language']: + response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language) + else: + response.delete_cookie(settings.LANGUAGE_COOKIE_NAME) + + return response return render(request, self.template_name, { 'form': form, diff --git a/netbox/netbox/preferences.py b/netbox/netbox/preferences.py index 5ef216259..9a6fe490c 100644 --- a/netbox/netbox/preferences.py +++ b/netbox/netbox/preferences.py @@ -1,4 +1,6 @@ +from django.conf import settings from django.utils.translation import gettext as _ + from netbox.registry import registry from users.preferences import UserPreference from utilities.paginator import EnhancedPaginator @@ -16,11 +18,18 @@ PREFERENCES = { 'ui.colormode': UserPreference( label=_('Color mode'), choices=( - ('light', 'Light'), - ('dark', 'Dark'), + ('light', _('Light')), + ('dark', _('Dark')), ), default='light', ), + 'locale.language': UserPreference( + label=_('Language'), + choices=( + ('', _('Auto')), + *settings.LANGUAGES, + ) + ), 'pagination.per_page': UserPreference( label=_('Page length'), choices=get_page_lengths(), @@ -30,9 +39,9 @@ PREFERENCES = { 'pagination.placement': UserPreference( label=_('Paginator placement'), choices=( - ('bottom', 'Bottom'), - ('top', 'Top'), - ('both', 'Both'), + ('bottom', _('Bottom')), + ('top', _('Top')), + ('both', _('Both')), ), description=_('Where the paginator controls will be displayed relative to a table'), default='bottom' diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 59e507d28..00f7c33b4 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -13,6 +13,7 @@ from django.contrib.messages import constants as messages from django.core.exceptions import ImproperlyConfigured, ValidationError from django.core.validators import URLValidator from django.utils.encoding import force_str +from django.utils.translation import gettext_lazy as _ try: import sentry_sdk except ModuleNotFoundError: @@ -721,6 +722,14 @@ RQ_QUEUES.update({ # Localization # +LANGUAGES = ( + ('en', _('English')), + ('es', _('Spanish')), + ('fr', _('French')), + ('pt', _('Portuguese')), + ('ru', _('Russian')), +) + LOCALE_PATHS = ( BASE_DIR + '/translations', ) diff --git a/netbox/users/forms/model_forms.py b/netbox/users/forms/model_forms.py index b0a43ef22..99320fa25 100644 --- a/netbox/users/forms/model_forms.py +++ b/netbox/users/forms/model_forms.py @@ -56,6 +56,7 @@ class UserConfigFormMetaclass(forms.models.ModelFormMetaclass): class UserConfigForm(BootstrapMixin, forms.ModelForm, metaclass=UserConfigFormMetaclass): fieldsets = ( (_('User Interface'), ( + 'locale.language', 'pagination.per_page', 'pagination.placement', 'ui.colormode',