Adds user-prefered admin language (#3310).

added prefered language field and migration

added form and view to select prefered language

Added some tests

modified tests

fix styleguide errors

activate middleware only for authenticated users

fixed typos

fixed test undoing language preferences

fixed lint issues

fixed tests

fixed message

change behaviour and more test added

added utf8 coding

[skip ci] initial documentation for preferred language

added contributor

refactor get_available_admin_languages

refactor get_available_admin_languages

make language name language aware

translate notifications to recipient language

make language name language aware

fixed lint
pull/2923/merge
Daniel Chimeno 2017-01-27 23:33:48 +01:00 zatwierdzone przez Bertrand Bordage
rodzic 911009473b
commit 72a935a8f0
13 zmienionych plików z 205 dodań i 8 usunięć

Wyświetl plik

@ -228,6 +228,7 @@ Contributors
* Thijs Kramer
* Ramon de Jezus
* Ross Curzon-Butler
* Daniel Chimeno
Translators
===========

Wyświetl plik

@ -17,6 +17,26 @@ The Wagtail admin backend has been translated into many different languages. You
If your language isn't listed on that page, you can easily contribute new languages or correct mistakes. Sign up and submit changes to `Transifex <https://www.transifex.com/torchbox/wagtail/>`_. Translation updates are typically merged into an official release within one month of being submitted.
Change Wagtail admin language on a per user basis
=================================================
.. versionadded:: 1.10
Logged users can set their preferred language from ``/admin/account/``.
By default, Wagtail provides a list of languages that have a coverage >= 90% translation.
It is possible to override this list by adding a setting configuration.
Example:
.. code-block:: python
from django.conf import settings
WAGTAILADMIN_PERMITTED_LANGUAGES = [ ('en' , 'English'), ('pt', 'Portuguese') ]
In case there is zero or one language permitted, the form will be hidden.
If there is no language selected either by the user or by the Site Administrator, the ``LANGUAGE_CODE`` wil be used.
Changing the primary language of your Wagtail installation
==========================================================

Wyświetl plik

@ -2,7 +2,9 @@ from __future__ import absolute_import, unicode_literals
from django.contrib.auth.views import redirect_to_login as auth_redirect_to_login
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.utils.translation import activate
from wagtail.utils.compat import user_is_anonymous
from wagtail.wagtailadmin import messages
@ -21,6 +23,8 @@ def require_admin_access(view_func):
return redirect_to_login(request)
if user.has_perms(['wagtailadmin.access_admin']):
if hasattr(user, 'wagtail_userprofile'):
activate(user.wagtail_userprofile.get_preferred_language())
return view_func(request, *args, **kwargs)
messages.error(request, _('You do not have permission to access the admin'))

Wyświetl plik

@ -16,7 +16,7 @@
<small class="col6">
{% trans "Your avatar image is provided by Gravatar and is connected to your email address. With a Gravatar account you can set an avatar for any number of other email addresses you use." %}
</small>
</li>
{% if show_change_password %}
<li class="row row-flush">
@ -40,6 +40,18 @@
</small>
</li>
{% endif %}
{% if show_preferred_language_preferences %}
<li class="row row-flush">
<div class="col6">
<a href="{% url 'wagtailadmin_account_language_preferences' %}" class="button button-primary">{% trans "Language preferences" %}</a>
</div>
<small class="col6">
{% trans "Choose the language you want to use here." %}
</small>
</li>
{% endif %}
</ul>
</div>
{% endblock %}

Wyświetl plik

@ -0,0 +1,20 @@
{% extends "wagtailadmin/base.html" %}
{% load i18n %}
{% block titletag %}{% trans "Language Preferences" %}{% endblock %}
{% block content %}
{% trans "Language Preferences" as prefs_str %}
{% include "wagtailadmin/shared/header.html" with title=prefs_str %}
<div class="nice-padding">
<form action="{% url 'wagtailadmin_account_language_preferences' %}" method="POST" novalidate>
{% csrf_token %}
<ul class="fields">
{% for field in form %}
{% include "wagtailadmin/shared/field_as_li.html" with field=field %}
{% endfor %}
<li class="submit"><input type="submit" value="{% trans 'Update' %}" class="button" /></li>
</ul>
</form>
</div>
{% endblock %}

Wyświetl plik

@ -8,6 +8,8 @@ from django.core.urlresolvers import reverse
from django.test import TestCase, override_settings
from wagtail.tests.utils import WagtailTestUtils
from wagtail.wagtailadmin.utils import (
WAGTAILADMIN_PROVIDED_LANGUAGES, get_available_admin_languages)
from wagtail.wagtailusers.models import UserProfile
@ -275,6 +277,51 @@ class TestAccountSection(TestCase, WagtailTestUtils):
self.assertFalse(profile.approved_notifications)
self.assertTrue(profile.rejected_notifications)
def test_language_preferences_view(self):
"""
This tests that the language preferences view responds with an index page
"""
# Get account page
response = self.client.get(reverse('wagtailadmin_account_language_preferences'))
# Check that the user received an account page
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'wagtailadmin/account/language_preferences.html')
# Page should contain a 'Language Preferences' title
self.assertContains(response, "Language Preferences")
def test_language_preferences_view_post(self):
"""
This post to the language preferences view and checks that the
user's profile is updated
"""
# Post new values to the language preferences page
post_data = {
'preferred_language': 'es'
}
response = self.client.post(reverse('wagtailadmin_account_language_preferences'), post_data)
# Check that the user was redirected to the account language preferences page
self.assertEqual(response.status_code, 200)
profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))
# Check that the language preferences are stored
self.assertEqual(profile.preferred_language, 'es')
@override_settings(WAGTAILADMIN_PERMITTED_LANGUAGES=[('en', 'English'), ('es', 'Spanish')])
def test_available_admin_languages_with_permitted_languages(self):
self.assertListEqual(get_available_admin_languages(), [('en', 'English'), ('es', 'Spanish')])
def test_available_admin_languages_by_default(self):
self.assertListEqual(get_available_admin_languages(), WAGTAILADMIN_PROVIDED_LANGUAGES)
@override_settings(WAGTAILADMIN_PERMITTED_LANGUAGES=[('en', 'English')])
def test_not_show_options_if_only_one_language_is_permitted(self):
response = self.client.post(reverse('wagtailadmin_account'))
self.assertNotContains(response, 'Language Preferences')
class TestAccountManagementForNonModerator(TestCase, WagtailTestUtils):
"""

Wyświetl plik

@ -44,6 +44,11 @@ urlpatterns = [
account.notification_preferences,
name='wagtailadmin_account_notification_preferences'
),
url(
r'^account/language_preferences/$',
account.language_preferences,
name='wagtailadmin_account_language_preferences'
),
url(r'^logout/$', account.logout, name='wagtailadmin_logout'),
]

Wyświetl plik

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import logging
@ -11,6 +12,7 @@ from django.db.models import Count, Q
from django.shortcuts import redirect
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.utils.translation import gettext_lazy, override
from modelcluster.fields import ParentalKey
from taggit.models import Tag
@ -19,6 +21,30 @@ from wagtail.wagtailusers.models import UserProfile
logger = logging.getLogger('wagtail.admin')
# Wagtail languages with >=90% coverage
# This list is manually maintained
WAGTAILADMIN_PROVIDED_LANGUAGES = [
('en', _('English')),
('de', gettext_lazy('German')),
('pt-br', gettext_lazy('Brazilian Portuguese')),
('es', gettext_lazy('Spanish')),
('ro', gettext_lazy('Romanian')),
('fr', gettext_lazy('French')),
('is-is', gettext_lazy('Icelandic')),
('it', gettext_lazy('Italian')),
('nb', gettext_lazy('Norwegian Bokmål')),
('pl', gettext_lazy('Polish')),
('pt-pt', gettext_lazy('Portuguese')),
('ru', gettext_lazy('Russian')),
('nl-nl', gettext_lazy('Netherlands Dutch')),
('fi', gettext_lazy('Finish')),
('ga', gettext_lazy('Galician'))
]
def get_available_admin_languages():
return getattr(settings, 'WAGTAILADMIN_PERMITTED_LANGUAGES', WAGTAILADMIN_PROVIDED_LANGUAGES)
def get_object_usage(obj):
"Returns a queryset of pages that link to a particular object"
@ -216,9 +242,11 @@ def send_notification(page_revision_id, notification, excluded_user_id):
# update context with this recipient
context["user"] = recipient
# Get email subject and content
email_subject = render_to_string(template_subject, context).strip()
email_content = render_to_string(template_text, context).strip()
# Translate text to the recipient language settings
with override(recipient.wagtail_userprofile.get_preferred_language()):
# Get email subject and content
email_subject = render_to_string(template_subject, context).strip()
email_content = render_to_string(template_text, context).strip()
kwargs = {}
if getattr(settings, 'WAGTAILADMIN_NOTIFICATION_USE_HTML', False):

Wyświetl plik

@ -10,13 +10,15 @@ from django.contrib.auth.forms import PasswordChangeForm
from django.http import Http404
from django.shortcuts import redirect, render
from django.utils.translation import ugettext as _
from django.utils.translation import activate
from django.views.decorators.cache import never_cache
from django.views.decorators.debug import sensitive_post_parameters
from wagtail.utils.compat import user_is_authenticated
from wagtail.wagtailadmin import forms
from wagtail.wagtailadmin.utils import get_available_admin_languages
from wagtail.wagtailcore.models import UserPagePermissionsProxy
from wagtail.wagtailusers.forms import NotificationPreferencesForm
from wagtail.wagtailusers.forms import NotificationPreferencesForm, PreferredLanguageForm
from wagtail.wagtailusers.models import UserProfile
@ -40,7 +42,8 @@ def account(request):
return render(request, 'wagtailadmin/account/account.html', {
'show_change_password': password_management_enabled() and request.user.has_usable_password(),
'show_notification_preferences': show_notification_preferences
'show_notification_preferences': show_notification_preferences,
'show_preferred_language_preferences': len(get_available_admin_languages()) > 1
})
@ -107,6 +110,23 @@ def notification_preferences(request):
})
def language_preferences(request):
if request.method == 'POST':
form = PreferredLanguageForm(request.POST, instance=UserProfile.get_for_user(request.user))
if form.is_valid():
user_profile = form.save()
# This will set the language only for this request/thread
activate(user_profile.preferred_language)
messages.success(request, _("Your preferences have been updated."))
else:
form = PreferredLanguageForm(instance=UserProfile.get_for_user(request.user))
return render(request, 'wagtailadmin/account/language_preferences.html', {
'form': form,
})
@sensitive_post_parameters()
@never_cache
def login(request):

Wyświetl plik

@ -1,7 +1,6 @@
from __future__ import absolute_import, unicode_literals
import django
from wagtail.wagtailcore.models import Site
@ -11,7 +10,6 @@ else:
MiddlewareMixin = object
class SiteMiddleware(MiddlewareMixin):
def process_request(self, request):
"""

Wyświetl plik

@ -12,6 +12,7 @@ from django.template.loader import render_to_string
from django.utils.html import mark_safe
from django.utils.translation import ugettext_lazy as _
from wagtail.wagtailadmin.utils import get_available_admin_languages
from wagtail.wagtailadmin.widgets import AdminPageChooser
from wagtail.wagtailcore import hooks
from wagtail.wagtailcore.models import (
@ -352,3 +353,14 @@ class NotificationPreferencesForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ("submitted_notifications", "approved_notifications", "rejected_notifications")
class PreferredLanguageForm(forms.ModelForm):
preferred_language = forms.ChoiceField(choices=get_available_admin_languages())
def __init__(self, *args, **kwargs):
super(PreferredLanguageForm, self).__init__(*args, **kwargs)
class Meta:
model = UserProfile
fields = ("preferred_language",)

Wyświetl plik

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-01-27 22:18
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wagtailusers', '0005_make_related_name_wagtail_specific'),
]
operations = [
migrations.AddField(
model_name='userprofile',
name='preferred_language',
field=models.CharField(default='', help_text='Select language for the admin', max_length=10, verbose_name='preferred language'),
),
]

Wyświetl plik

@ -30,10 +30,20 @@ class UserProfile(models.Model):
help_text=_("Receive notification when your page edit is rejected")
)
preferred_language = models.CharField(
verbose_name=_('preferred language'),
max_length=10,
help_text=_("Select language for the admin"),
default=''
)
@classmethod
def get_for_user(cls, user):
return cls.objects.get_or_create(user=user)[0]
def get_preferred_language(self):
return self.preferred_language or settings.LANGUAGE_CODE
def __str__(self):
return self.user.get_username()