diff --git a/docs/reference/hooks.rst b/docs/reference/hooks.rst index 9eb9b750f..b281efac1 100644 --- a/docs/reference/hooks.rst +++ b/docs/reference/hooks.rst @@ -120,6 +120,33 @@ Hooks for building new areas of the admin interface (alongside pages, images, do ``url`` (optional) A URL to an index page that lists the objects being described. +.. _register_account_menu_item: + +``register_account_menu_item`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Add an item to the My Account page within the Wagtail admin. The callable + for this hook should return a dict with values for the keys ``url``, + ``label`` and ``help_text``. For example: + + .. code-block:: python + + from django.utils.translation import ugettext_lazy as _ + from wagtail.core import hooks + + @hooks.register('register_account_menu_item') + def register_account_set_gravatar(request): + return { + 'url': 'https://gravatar.com/emails/', + 'label': _('Set gravatar'), + 'help_text': _( + "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." + ) + } + + .. _register_admin_menu_item: diff --git a/wagtail/admin/templates/wagtailadmin/account/account.html b/wagtail/admin/templates/wagtailadmin/account/account.html index 4527f8902..28a8f34f0 100644 --- a/wagtail/admin/templates/wagtailadmin/account/account.html +++ b/wagtail/admin/templates/wagtailadmin/account/account.html @@ -8,50 +8,14 @@
{% endblock %} diff --git a/wagtail/admin/tests/test_account_management.py b/wagtail/admin/tests/test_account_management.py index 9ea6955a2..1a24c60ac 100644 --- a/wagtail/admin/tests/test_account_management.py +++ b/wagtail/admin/tests/test_account_management.py @@ -413,9 +413,12 @@ class TestAccountManagementForAdminOnlyUser(TestCase, WagtailTestUtils): Test that the user is not even shown the link to the notification preferences view """ + expected_url = reverse('wagtailadmin_account_notification_preferences') + response = self.client.get(reverse('wagtailadmin_account')) - self.assertEqual(response.context['show_notification_preferences'], False) - self.assertNotContains(response, reverse('wagtailadmin_account_notification_preferences')) + account_urls = [item['url'] for item in response.context['items']] + self.assertFalse(expected_url in account_urls) + self.assertNotContains(response, expected_url) # safety check that checking for absence/presence of urls works self.assertContains(response, reverse('wagtailadmin_home')) diff --git a/wagtail/admin/views/account.py b/wagtail/admin/views/account.py index 76ee72598..122286f7c 100644 --- a/wagtail/admin/views/account.py +++ b/wagtail/admin/views/account.py @@ -13,8 +13,7 @@ from django.views.decorators.cache import never_cache from django.views.decorators.debug import sensitive_post_parameters from wagtail.admin import forms -from wagtail.admin.utils import get_available_admin_languages -from wagtail.core.models import UserPagePermissionsProxy +from wagtail.core import hooks from wagtail.users.forms import NotificationPreferencesForm, PreferredLanguageForm from wagtail.users.models import UserProfile from wagtail.utils.loading import get_custom_form @@ -43,13 +42,15 @@ def password_reset_enabled(): # Views def account(request): - user_perms = UserPagePermissionsProxy(request.user) - show_notification_preferences = user_perms.can_edit_pages() or user_perms.can_publish_pages() + items = [] + + for fn in hooks.get_hooks('register_account_menu_item'): + item = fn(request) + if item: + items.append(item) 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_preferred_language_preferences': len(get_available_admin_languages()) > 1 + 'items': items, }) diff --git a/wagtail/admin/wagtail_hooks.py b/wagtail/admin/wagtail_hooks.py index dc26c9c81..5829173db 100644 --- a/wagtail/admin/wagtail_hooks.py +++ b/wagtail/admin/wagtail_hooks.py @@ -15,10 +15,12 @@ from wagtail.admin.rich_text.converters.html_to_contentstate import ( BlockElementHandler, ExternalLinkElementHandler, HorizontalRuleHandler, InlineStyleElementHandler, ListElementHandler, ListItemElementHandler, PageLinkElementHandler) from wagtail.admin.search import SearchArea -from wagtail.admin.utils import user_has_any_page_permission +from wagtail.admin.utils import get_available_admin_languages, user_has_any_page_permission +from wagtail.admin.views.account import password_management_enabled from wagtail.admin.viewsets import viewsets from wagtail.admin.widgets import Button, ButtonWithDropdownFromHook, PageListingButton from wagtail.core import hooks +from wagtail.core.models import UserPagePermissionsProxy from wagtail.core.permissions import collection_permission_policy from wagtail.core.rich_text.pages import PageLinkHandler from wagtail.core.whitelist import allow_without_attributes, attribute_rule, check_url @@ -189,6 +191,50 @@ def register_viewsets_urls(): return viewsets.get_urlpatterns() +@hooks.register('register_account_menu_item') +def register_account_set_gravatar(request): + return { + 'url': 'https://gravatar.com/emails/', + 'label': _('Set gravatar'), + 'help_text': _( + "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." + ) + } + + +@hooks.register('register_account_menu_item') +def register_account_change_password(request): + if password_management_enabled() and request.user.has_usable_password(): + return { + 'url': reverse('wagtailadmin_account_change_password'), + 'label': _('Change password'), + 'help_text': _('Change the password you use to log in.'), + } + + +@hooks.register('register_account_menu_item') +def register_account_notification_preferences(request): + user_perms = UserPagePermissionsProxy(request.user) + if user_perms.can_edit_pages() or user_perms.can_publish_pages(): + return { + 'url': reverse('wagtailadmin_account_notification_preferences'), + 'label': _('Notification preferences'), + 'help_text': _('Choose which email notifications to receive.'), + } + + +@hooks.register('register_account_menu_item') +def register_account_preferred_language_preferences(request): + if len(get_available_admin_languages()) > 1: + return { + 'url': reverse('wagtailadmin_account_language_preferences'), + 'label': _('Language preferences'), + 'help_text': _('Choose the language you want to use here.'), + } + + @hooks.register('register_rich_text_features') def register_core_features(features): # Hallo.js