kopia lustrzana https://github.com/wagtail/wagtail
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 lintpull/2923/merge
rodzic
911009473b
commit
72a935a8f0
|
@ -228,6 +228,7 @@ Contributors
|
|||
* Thijs Kramer
|
||||
* Ramon de Jezus
|
||||
* Ross Curzon-Butler
|
||||
* Daniel Chimeno
|
||||
|
||||
Translators
|
||||
===========
|
||||
|
|
|
@ -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
|
||||
==========================================================
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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",)
|
||||
|
|
|
@ -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'),
|
||||
),
|
||||
]
|
|
@ -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()
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue