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:
fonfon 2015-11-18 18:29:54 +01:00
parent f8f7a979f2
commit aeaa6ab800
3 changed files with 60 additions and 8 deletions

View File

@ -213,6 +213,17 @@ def configure_django():
if cfg.secure_proxy_ssl_header:
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(
ALLOWED_HOSTS=['*'],
CACHES={'default':
@ -222,6 +233,7 @@ def configure_django():
'NAME': cfg.store_file}},
DEBUG=cfg.debug,
INSTALLED_APPS=applications,
LANGUAGES=languages,
LOGGING=logging_configuration,
LOGIN_URL='users:login',
LOGIN_REDIRECT_URL='apps:index',

View File

@ -23,7 +23,9 @@ from django import forms
from django.contrib import messages
from django.core import validators
from django.core.exceptions import ValidationError
from django.conf import settings
from django.template.response import TemplateResponse
from django.utils import translation
from django.utils.translation import ugettext as _, ugettext_lazy
import logging
import re
@ -51,6 +53,16 @@ def get_domainname():
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):
"""Trim the contents of a CharField"""
def clean(self, value):
@ -104,6 +116,14 @@ class ConfigurationForm(forms.Form):
ugettext_lazy('Invalid domain name')),
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():
"""Initialize the module"""
@ -114,7 +134,7 @@ def init():
def index(request):
"""Serve the configuration form"""
status = get_status()
status = get_status(request)
form = None
@ -124,7 +144,7 @@ def index(request):
# pylint: disable-msg=E1101
if form.is_valid():
_apply_changes(request, status, form.cleaned_data)
status = get_status()
status = get_status(request)
form = ConfigurationForm(initial=status,
prefix='configuration')
else:
@ -135,10 +155,11 @@ def index(request):
'form': form})
def get_status():
def get_status(request):
"""Return the current status"""
return {'hostname': get_hostname(),
'domainname': get_domainname()}
'domainname': get_domainname(),
'language': get_language(request)}
def _apply_changes(request, old_status, new_status):
@ -151,8 +172,6 @@ def _apply_changes(request, old_status, new_status):
.format(exception=exception))
else:
messages.success(request, _('Hostname set'))
else:
messages.info(request, _('Hostname is unchanged'))
if old_status['domainname'] != new_status['domainname']:
try:
@ -162,8 +181,17 @@ def _apply_changes(request, old_status, new_status):
.format(exception=exception))
else:
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):

View File

@ -19,8 +19,11 @@
Tests for config module.
"""
import os
import unittest
from plinth import __main__ as plinth_main
from ..config import ConfigurationForm
@ -65,3 +68,12 @@ class TestConfig(unittest.TestCase):
form = ConfigurationForm({'hostname': 'example',
'domainname': domainname})
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))