some ideas to restrict page creation and page deletion

362 views
Skip to first unread message

Robert Slotboom

unread,
Jun 8, 2016, 9:35:03 AM6/8/16
to Wagtail support
Hi folks,

After reading some posts regarding page deletion resulting in site deletion etc. I wrote the following stuff.

A project is based on wagtail and is supposed to host only one site.
Within the project are two apps: cms_core, wich will become a package, and cms, a site specific app.

The customizations are meant to prevent root and homepage deletions.
Another customization is to prevent the creation of additional homepages beneath root.


cms_core.models.py  ( will become a package )

class RootPage(Page):
   
## Root accepts only HomePges
   
...
    parent_page_types
= []
    subpage_types
= ['cms.HomePage',]

   
class Meta:
        verbose_name
= _('RootPage')

class HomePageBase(Page):
   
## This Base is abstract
   
...
   
class Meta:
        verbose_name
= _('HomepageBase')
       
abstract = True



cms.models ( site specific app )

from cms_core.models import HomePageBase

class HomePage(HomePageBase):
    ## HomePage for the site accepts only RootPage as parent
    ...
    parent_page_types = ['cms_core.RootPage']

    class Meta:
        verbose_name = _('Homepage')



cms_core.templates.wagtailadmin.pages.listing._parent_page_title_explore.html

## Based on wgatail’s template

{% load i18n %}
{% load wagtailadmin_tags %}
{% load cms_core_admin_tags %}
...
<ul class="actions">
    {% custom_page_listing_buttons parent_page parent_page_perms is_parent=True %}
</ul>



cms_core.templates.wagtailadmin.pages.listing._page_title_explore.html

## Also based on wgatail’s template

{%
load cms_core_admin_tags %}
...
<ul class="actions">
    {% custom_page_listing_buttons page page_perms %}
</
ul>


## Rewritten wagtail tag
...

@register.inclusion_tag("wagtailadmin/pages/listing/_buttons.html", takes_context=True)
def custom_page_listing_buttons(context, page, page_perms, is_parent=False):
    site = None
    request = context.get('request', None)
    if request:
        site = request.site
    button_hooks = hooks.get_hooks('register_custom_page_listing_buttons')
    buttons = sorted(itertools.chain.from_iterable(
    hook(site, page, page_perms, is_parent)
        for hook in button_hooks))
    return {'page': page, 'buttons': buttons}



## Rewritten wagtail hook and widget

from wagtail.wagtailadmin import widgets as wagtailadmin_widgets
...

class CustomButtonWithDropdownFromHook(wagtailadmin_widgets.ButtonWithDropdownFromHook):
    def __init__(self, label, hook_name, site, page, page_perms, is_parent, **kwargs):
        self.site = site
        super().__init__(label, hook_name, page, page_perms, is_parent, **kwargs)

    def get_buttons_in_dropdown(self):
        button_hooks = hooks.get_hooks(self.hook_name)
        return sorted(itertools.chain.from_iterable(
            hook(self.site, self.page, self.page_perms, self.is_parent)
            for hook in button_hooks))

@hooks.register('register_custom_page_listing_buttons')
def custom_page_listing_buttons(site, page, page_perms, is_parent=False):

    ... 
    if page_perms.can_add_subpage():
        if is_parent:
            if not page.is_root():
                yield Button('Add child page' ...)
        elif page.is_root():
            yield PageListingButton('Add homepage' ...)
        else:
            yield PageListingButton('Add child page' ...)

    yield CustomButtonWithDropdownFromHook(
        'More',
        hook_name='register_custom_page_listing_more_buttons',
        site=site,
        page=page,
        page_perms=page_perms,
        is_parent=is_parent,
        attrs={'target': '_blank', 'title': _('View more options')}, priority=50)

@hooks.register('register_custom_page_listing_more_buttons')
def custom_page_listing_more_buttons(site, page, page_perms, is_parent=False):

    is_home_page = False
    home_page = site.root_page if site else None
    if home_page:
        is_home_page = home_page.id == page.id
    if page_perms.can_move() and not is_home_page:
       yield Button('Move' ...)
    if not page.is_root() and not is_home_page:
        yield Button('Copy' ...)
    if page_perms.can_delete() and not is_home_page:
        yield Button('Delete' ...)

    ...



cms_core.templates.wagtailadmin.pages.edit.html

## Based on wgatail’s template
...
{% if not is_revision and page_perms.can_delete %}
    {% if request.site.root_page.id != page.id %}
        
<li><a href="{% url 'wagtailadmin_pages:delete' page.id %}" class="shortcut">{% trans 'Delete' %}</a></li>
    {% endif %}
{% endif %}
...



## Catch edit url

from cms_core.views.pages import delete
...

urlpatterns
= [
    ...
    url
(r'^admin/pages/(\d+)/delete/$', delete),
    url
(r'^admin/', include(wagtailadmin_urls)),
    ...
]



## Based on wgatail view
...

def delete(request, page_id):
    page
= get_object_or_404(Page, id=page_id)
    message = None
    
if not page.permissions_for_user(request.user).can_delete():
        
raise PermissionDenied
    if page.is_root():
        message =
 _("Page '{0}' is the root and cannot be deleted.").format(page.title)
    elif request.site.root_page.id == page.id:
        message =
 _("Page '{0}' is the homepage and cannot be deleted.").format(page.title))
   
    if message:
        messages.warning(request, message.format(page.title))
        
return redirect('wagtailadmin_explore', page.id)
    ...
 

The code is working fine but I want to ask if this is a decent approach?


Best regards,

Robert







Robert Slotboom

unread,
Jun 8, 2016, 10:14:43 AM6/8/16
to Wagtail support
One addition to get rid of the button dropdown for root..

...

@hooks.register('register_custom_page_listing_buttons')
def custom_page_listing_buttons(site, page, page_perms, is_parent=False):
   
...

   
if not is_parent:
       
yield CustomButtonWithDropdownFromHook(
            _
('More'),
Reply all
Reply to author
Forward
0 new messages