mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-08-26 12:46:08 +00:00
Adds a 'language' dropdown field to the system configuration
- The language choice is stored with the session, not persistently - This removes confirmation messages if nothing was changed
This commit is contained in:
parent
f8f7a979f2
commit
aeaa6ab800
@ -213,6 +213,17 @@ def configure_django():
|
|||||||
if cfg.secure_proxy_ssl_header:
|
if cfg.secure_proxy_ssl_header:
|
||||||
secure_proxy_ssl_header = (cfg.secure_proxy_ssl_header, 'https')
|
secure_proxy_ssl_header = (cfg.secure_proxy_ssl_header, 'https')
|
||||||
|
|
||||||
|
# Read translated languages from the 'locale' directory
|
||||||
|
languages = [('en', 'English')]
|
||||||
|
locale_dir = os.path.join(os.path.dirname(__file__), 'locale')
|
||||||
|
if os.path.isdir(locale_dir):
|
||||||
|
translated_language_codes = next(os.walk(locale_dir))[1]
|
||||||
|
all_languages = dict(django.conf.global_settings.LANGUAGES)
|
||||||
|
for code in translated_language_codes:
|
||||||
|
if code in all_languages:
|
||||||
|
languages.append((code, all_languages[code]))
|
||||||
|
languages = sorted(languages, key=lambda tup: tup[1])
|
||||||
|
|
||||||
django.conf.settings.configure(
|
django.conf.settings.configure(
|
||||||
ALLOWED_HOSTS=['*'],
|
ALLOWED_HOSTS=['*'],
|
||||||
CACHES={'default':
|
CACHES={'default':
|
||||||
@ -222,6 +233,7 @@ def configure_django():
|
|||||||
'NAME': cfg.store_file}},
|
'NAME': cfg.store_file}},
|
||||||
DEBUG=cfg.debug,
|
DEBUG=cfg.debug,
|
||||||
INSTALLED_APPS=applications,
|
INSTALLED_APPS=applications,
|
||||||
|
LANGUAGES=languages,
|
||||||
LOGGING=logging_configuration,
|
LOGGING=logging_configuration,
|
||||||
LOGIN_URL='users:login',
|
LOGIN_URL='users:login',
|
||||||
LOGIN_REDIRECT_URL='apps:index',
|
LOGIN_REDIRECT_URL='apps:index',
|
||||||
|
|||||||
@ -23,7 +23,9 @@ from django import forms
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.conf import settings
|
||||||
from django.template.response import TemplateResponse
|
from django.template.response import TemplateResponse
|
||||||
|
from django.utils import translation
|
||||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
@ -51,6 +53,16 @@ def get_domainname():
|
|||||||
return '.'.join(fqdn.split('.')[1:])
|
return '.'.join(fqdn.split('.')[1:])
|
||||||
|
|
||||||
|
|
||||||
|
def get_language(request):
|
||||||
|
"""Return the current language setting"""
|
||||||
|
# TODO: Store the language per user in kvstore,
|
||||||
|
# taking care of setting language on login, and adapting kvstore when
|
||||||
|
# renaming/deleting users
|
||||||
|
|
||||||
|
# The session contains more accurate information than request.LANGUAGE_CODE
|
||||||
|
return request.session[translation.LANGUAGE_SESSION_KEY]
|
||||||
|
|
||||||
|
|
||||||
class TrimmedCharField(forms.CharField):
|
class TrimmedCharField(forms.CharField):
|
||||||
"""Trim the contents of a CharField"""
|
"""Trim the contents of a CharField"""
|
||||||
def clean(self, value):
|
def clean(self, value):
|
||||||
@ -104,6 +116,14 @@ class ConfigurationForm(forms.Form):
|
|||||||
ugettext_lazy('Invalid domain name')),
|
ugettext_lazy('Invalid domain name')),
|
||||||
domain_label_validator])
|
domain_label_validator])
|
||||||
|
|
||||||
|
language = forms.ChoiceField(
|
||||||
|
label=ugettext_lazy('Language'),
|
||||||
|
help_text=\
|
||||||
|
ugettext_lazy('Language for this freedombox web administration '
|
||||||
|
'interface'),
|
||||||
|
required=False,
|
||||||
|
choices=settings.LANGUAGES)
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
"""Initialize the module"""
|
"""Initialize the module"""
|
||||||
@ -114,7 +134,7 @@ def init():
|
|||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
"""Serve the configuration form"""
|
"""Serve the configuration form"""
|
||||||
status = get_status()
|
status = get_status(request)
|
||||||
|
|
||||||
form = None
|
form = None
|
||||||
|
|
||||||
@ -124,7 +144,7 @@ def index(request):
|
|||||||
# pylint: disable-msg=E1101
|
# pylint: disable-msg=E1101
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
_apply_changes(request, status, form.cleaned_data)
|
_apply_changes(request, status, form.cleaned_data)
|
||||||
status = get_status()
|
status = get_status(request)
|
||||||
form = ConfigurationForm(initial=status,
|
form = ConfigurationForm(initial=status,
|
||||||
prefix='configuration')
|
prefix='configuration')
|
||||||
else:
|
else:
|
||||||
@ -135,10 +155,11 @@ def index(request):
|
|||||||
'form': form})
|
'form': form})
|
||||||
|
|
||||||
|
|
||||||
def get_status():
|
def get_status(request):
|
||||||
"""Return the current status"""
|
"""Return the current status"""
|
||||||
return {'hostname': get_hostname(),
|
return {'hostname': get_hostname(),
|
||||||
'domainname': get_domainname()}
|
'domainname': get_domainname(),
|
||||||
|
'language': get_language(request)}
|
||||||
|
|
||||||
|
|
||||||
def _apply_changes(request, old_status, new_status):
|
def _apply_changes(request, old_status, new_status):
|
||||||
@ -151,8 +172,6 @@ def _apply_changes(request, old_status, new_status):
|
|||||||
.format(exception=exception))
|
.format(exception=exception))
|
||||||
else:
|
else:
|
||||||
messages.success(request, _('Hostname set'))
|
messages.success(request, _('Hostname set'))
|
||||||
else:
|
|
||||||
messages.info(request, _('Hostname is unchanged'))
|
|
||||||
|
|
||||||
if old_status['domainname'] != new_status['domainname']:
|
if old_status['domainname'] != new_status['domainname']:
|
||||||
try:
|
try:
|
||||||
@ -162,8 +181,17 @@ def _apply_changes(request, old_status, new_status):
|
|||||||
.format(exception=exception))
|
.format(exception=exception))
|
||||||
else:
|
else:
|
||||||
messages.success(request, _('Domain name set'))
|
messages.success(request, _('Domain name set'))
|
||||||
else:
|
|
||||||
messages.info(request, _('Domain name is unchanged'))
|
if old_status['language'] != new_status['language']:
|
||||||
|
language = new_status['language']
|
||||||
|
try:
|
||||||
|
translation.activate(language)
|
||||||
|
request.session[translation.LANGUAGE_SESSION_KEY] = language
|
||||||
|
except Exception as exception:
|
||||||
|
messages.error(request, _('Error setting language: {exception}')
|
||||||
|
.format(exception=exception))
|
||||||
|
else:
|
||||||
|
messages.success(request, _('Language changed'))
|
||||||
|
|
||||||
|
|
||||||
def set_hostname(hostname):
|
def set_hostname(hostname):
|
||||||
|
|||||||
@ -19,8 +19,11 @@
|
|||||||
Tests for config module.
|
Tests for config module.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
from plinth import __main__ as plinth_main
|
||||||
|
|
||||||
from ..config import ConfigurationForm
|
from ..config import ConfigurationForm
|
||||||
|
|
||||||
|
|
||||||
@ -65,3 +68,12 @@ class TestConfig(unittest.TestCase):
|
|||||||
form = ConfigurationForm({'hostname': 'example',
|
form = ConfigurationForm({'hostname': 'example',
|
||||||
'domainname': domainname})
|
'domainname': domainname})
|
||||||
self.assertFalse(form.is_valid())
|
self.assertFalse(form.is_valid())
|
||||||
|
|
||||||
|
def test_locale_path(self):
|
||||||
|
"""
|
||||||
|
Test that the 'locale' directory is in the same folder as __main__.py.
|
||||||
|
This is required for detecting translated languages.
|
||||||
|
"""
|
||||||
|
plinth_dir = os.path.dirname(plinth_main.__file__)
|
||||||
|
locale_dir = os.path.join(plinth_dir, 'locale')
|
||||||
|
self.assertTrue(os.path.isdir(locale_dir))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user