Move action menu items into individually renderable components

This commit is contained in:
Matt Westcott 2018-09-18 17:28:44 +01:00 committed by Karl Hobley
parent b3f1f50fba
commit bea004cc75
9 changed files with 140 additions and 36 deletions

View file

@ -0,0 +1,2 @@
{% load i18n %}
<li><a href="{% url 'wagtailadmin_pages:delete' page.id %}" class="shortcut">{% trans 'Delete' %}</a></li>

View file

@ -0,0 +1,6 @@
{% if show_menu %}
<div class="dropdown-toggle icon icon-arrow-up"></div>
<ul role="menu">
{% for item in rendered_menu_items %}{{ item }}{% endfor %}
</ul>
{% endif %}

View file

@ -0,0 +1,4 @@
{% load i18n %}
<li>
<button type="submit" name="action-publish" value="action-publish" class="button button-longrunning {% if is_revision %}warning{% endif %}" tabindex="3" data-clicked-text="{% trans 'Publishing…' %}"><span class="icon icon-spinner"></span><em>{% if is_revision %}{% trans 'Publish this revision' %}{% else %}{% trans 'Publish' %}{% endif %}</em></button>
</li>

View file

@ -0,0 +1,2 @@
{% load i18n %}
<li><input type="submit" name="action-submit" value="{% trans 'Submit for moderation' %}" class="button" /></li>

View file

@ -0,0 +1,2 @@
{% load i18n %}
<li><a href="{% url 'wagtailadmin_pages:unpublish' page.id %}">{% trans 'Unpublish' %}</a></li>

View file

@ -23,21 +23,12 @@
<input type="hidden" name="next" value="{{ next }}">
{{ edit_handler.render_form_content }}
{% page_permissions parent_page as parent_page_perms %}
<footer>
<ul>
<li class="actions">
<div class="dropdown dropup dropdown-button match-width">
<button type="submit" class="button action-save button-longrunning" tabindex="3" data-clicked-text="{% trans 'Saving…' %}"><span class="icon icon-spinner"></span><em>{% trans 'Save draft' %}</em></button>
<div class="dropdown-toggle icon icon-arrow-up"></div>
<ul role="menu">
{% if parent_page_perms.can_publish_subpage %}
<li>
<button type="submit" name="action-publish" value="action-publish" class="button button-longrunning" tabindex="3" data-clicked-text="{% trans 'Publishing…' %}" {% if page.locked %}disabled {% endif %}><span class="icon icon-spinner"></span><em>{% trans 'Publish' %}</em></button>
</li>
{% endif %}
<li><input type="submit" name="action-submit" value="{% trans 'Submit for moderation' %}" class="button" /></li>
</ul>
{% page_action_menu action_menu_items view='create' parent_page=parent_page %}
</div>
</li>

View file

@ -40,25 +40,7 @@
<div class="dropdown dropup dropdown-button match-width {% if is_revision %}warning{% endif %}">
<button type="submit" class="button action-save button-longrunning {% if is_revision %}warning{% endif %}" tabindex="3" data-clicked-text="{% trans 'Saving…' %}" {% if page.locked %}disabled {% endif %}><span class="icon icon-spinner"></span><em>{% if page.locked %}{% trans 'Page locked' %}{% else %}{% if is_revision %}{% trans 'Replace current draft' %}{% else %}{% trans 'Save draft' %}{% endif %}{% endif %}</em></button>
{% if not page.locked %}
<div class="dropdown-toggle icon icon-arrow-up"></div>
<ul role="menu">
{% if not is_revision and page_perms.can_unpublish %}
<li><a href="{% url 'wagtailadmin_pages:unpublish' page.id %}">{% trans 'Unpublish' %}</a></li>
{% endif %}
{% if not is_revision and page_perms.can_delete %}
<li><a href="{% url 'wagtailadmin_pages:delete' page.id %}" class="shortcut">{% trans 'Delete' %}</a></li>
{% endif %}
{% if page_perms.can_publish %}
<li>
<button type="submit" name="action-publish" value="action-publish" class="button button-longrunning {% if is_revision %}warning{% endif %}" tabindex="3" data-clicked-text="{% trans 'Publishing…' %}" {% if page.locked %}disabled {% endif %}><span class="icon icon-spinner"></span><em>{% if is_revision %}{% trans 'Publish this revision' %}{% else %}{% trans 'Publish' %}{% endif %}</em></button>
</li>
{% endif %}
{% if not is_revision %}
<li><input type="submit" name="action-submit" value="{% trans 'Submit for moderation' %}" class="button" /></li>
{% endif %}
</ul>
{% endif %}
{% page_action_menu action_menu_items view=view_type page=page %}
</div>
</li>

View file

@ -113,6 +113,15 @@ def widgettype(bound_field):
return ""
def _get_user_page_permissions(context):
# Create a UserPagePermissionsProxy object to represent the user's global permissions, and
# cache it in the context for the duration of the page request, if one does not exist already
if 'user_page_permissions' not in context:
context['user_page_permissions'] = UserPagePermissionsProxy(context['request'].user)
return context['user_page_permissions']
@register.simple_tag(takes_context=True)
def page_permissions(context, page):
"""
@ -120,13 +129,7 @@ def page_permissions(context, page):
Sets the variable 'page_perms' to a PagePermissionTester object that can be queried to find out
what actions the current logged-in user can perform on the given page.
"""
# Create a UserPagePermissionsProxy object to represent the user's global permissions, and
# cache it in the context for the duration of the page request, if one does not exist already
if 'user_page_permissions' not in context:
context['user_page_permissions'] = UserPagePermissionsProxy(context['request'].user)
# Now retrieve a PagePermissionTester from it, specific to the given page
return context['user_page_permissions'].for_page(page)
return _get_user_page_permissions(context).for_page(page)
@register.simple_tag(takes_context=True)
@ -392,3 +395,24 @@ def avatar_url(user, size=50):
return gravatar_url
return static('wagtailadmin/images/default-user-avatar.png')
@register.inclusion_tag("wagtailadmin/pages/action_menu/menu.html", takes_context=True)
def page_action_menu(context, menu_items, **kwargs):
menu_item_context = kwargs
menu_item_context.update({
'user_page_permissions': _get_user_page_permissions(context),
})
visible_menu_items = [
menu_item for menu_item in menu_items
if menu_item.is_shown(context['request'], menu_item_context)
]
return {
'show_menu': bool(visible_menu_items),
'rendered_menu_items': [
menu_item.render_html(context['request'], menu_item_context)
for menu_item in visible_menu_items
]
}

View file

@ -28,6 +28,92 @@ from wagtail.search.query import MATCH_ALL
from wagtail.utils.pagination import paginate
class ActionMenuItem:
"""Defines an item in the actions drop-up on the page creation/edit view"""
def is_shown(self, request, context):
"""
Whether this action should be shown on this request; permission checks etc should go here.
By default, actions are shown for unlocked pages, hidden for locked pages
request = the current request object
context = dictionary containing at least:
'view' = 'create', 'edit' or 'revisions_revert'
'page' (if view = 'edit' or 'revisions_revert') = the page being edited
'parent_page' (if view = 'create') = the parent page of the page being created
'user_page_permissions' = a UserPagePermissionsProxy for the current user, to test permissions against
"""
return (context['view'] == 'create' or not context['page'].locked)
def get_context(self, request, parent_context):
"""Defines context for the template, overridable to use more data"""
return parent_context.copy()
def render_html(self, request, parent_context):
context = self.get_context(request, parent_context)
return render_to_string(self.template, context, request=request)
class PublishMenuItem(ActionMenuItem):
template = 'wagtailadmin/pages/action_menu/publish.html'
def is_shown(self, request, context):
if context['view'] == 'create':
return context['user_page_permissions'].for_page(context['parent_page']).can_publish_subpage()
else: # view == 'edit' or 'revisions_revert'
return (
not context['page'].locked and
context['user_page_permissions'].for_page(context['page']).can_publish()
)
def get_context(self, request, parent_context):
context = super().get_context(request, parent_context)
context['is_revision'] = (context['view'] == 'revisions_revert')
return context
class SubmitForModerationMenuItem(ActionMenuItem):
template = 'wagtailadmin/pages/action_menu/submit_for_moderation.html'
def is_shown(self, request, context):
if context['view'] == 'create':
return True
elif context['view'] == 'edit':
return not context['page'].locked
else: # context == revisions_revert
return False
class UnpublishMenuItem(ActionMenuItem):
template = 'wagtailadmin/pages/action_menu/unpublish.html'
def is_shown(self, request, context):
return (
context['view'] == 'edit' and
not context['page'].locked and
context['user_page_permissions'].for_page(context['page']).can_unpublish()
)
class DeleteMenuItem(ActionMenuItem):
template = 'wagtailadmin/pages/action_menu/delete.html'
def is_shown(self, request, context):
return (
context['view'] == 'edit' and
not context['page'].locked and
context['user_page_permissions'].for_page(context['page']).can_delete()
)
ACTION_MENU_ITEMS = [
UnpublishMenuItem(),
DeleteMenuItem(),
PublishMenuItem(),
SubmitForModerationMenuItem(),
]
def get_valid_next_url_from_request(request):
next_url = request.POST.get('next') or request.GET.get('next')
if not next_url or not is_safe_url(url=next_url, allowed_hosts={request.get_host()}):
@ -303,6 +389,7 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_
'page_class': page_class,
'parent_page': parent_page,
'edit_handler': edit_handler,
'action_menu_items': ACTION_MENU_ITEMS,
'preview_modes': page.preview_modes,
'form': form,
'next': next_url,
@ -526,11 +613,13 @@ def edit(request, page_id):
page_for_status = page
return render(request, 'wagtailadmin/pages/edit.html', {
'view_type': 'edit',
'page': page,
'page_for_status': page_for_status,
'content_type': content_type,
'edit_handler': edit_handler,
'errors_debug': errors_debug,
'action_menu_items': ACTION_MENU_ITEMS,
'preview_modes': page.preview_modes,
'form': form,
'next': next_url,
@ -1134,12 +1223,14 @@ def revisions_revert(request, page_id, revision_id):
))
return render(request, 'wagtailadmin/pages/edit.html', {
'view_type': 'revisions_revert',
'page': page,
'revision': revision,
'is_revision': True,
'content_type': content_type,
'edit_handler': edit_handler,
'errors_debug': None,
'action_menu_items': ACTION_MENU_ITEMS,
'preview_modes': page.preview_modes,
'form': form, # Used in unit tests
})