diff --git a/tailbone/templates/master/delete.mako b/tailbone/templates/master/delete.mako new file mode 100644 index 00000000..e1572a67 --- /dev/null +++ b/tailbone/templates/master/delete.mako @@ -0,0 +1,41 @@ +## -*- coding: utf-8 -*- +<%inherit file="/base.mako" /> + +<%def name="title()">Delete ${model_title}: ${unicode(instance)} + +<%def name="context_menu_items()"> +
  • ${h.link_to("Back to {}".format(model_title_plural), url(route_prefix))}
  • + % if master.viewable and request.has_perm('{}.view'.format(permission_prefix)): +
  • ${h.link_to("View this {}".format(model_title), action_url('view', instance))}
  • + % endif + % if master.editable and request.has_perm('{}.edit'.format(permission_prefix)): +
  • ${h.link_to("Edit this {}".format(model_title), action_url('edit', instance))}
  • + % endif + % if master.creatable and request.has_perm('{}.create'.format(permission_prefix)): +
  • ${h.link_to("Create a new {}".format(model_title), url('{}.create'.format(route_prefix)))}
  • + % endif + + +<%def name="confirmation()"> +
    +

    Are you sure about this?

    + + ${h.form(request.current_route_url())} +
    + + Whoops, nevermind... +
    + ${h.end_form()} + + + + +

    You are about to delete the following ${model_title} record:

    + +
    + ${form.render()|n} +
    + +${self.confirmation()} diff --git a/tailbone/templates/master/edit.mako b/tailbone/templates/master/edit.mako index a1c9dd40..b1fe85d4 100644 --- a/tailbone/templates/master/edit.mako +++ b/tailbone/templates/master/edit.mako @@ -4,12 +4,15 @@ <%def name="title()">${model_title}: ${unicode(instance)} <%def name="context_menu_items()"> -
  • ${h.link_to("Back to {0}".format(model_title_plural), url(route_prefix))}
  • - % if master.viewable and request.has_perm('{0}.view'.format(permission_prefix)): -
  • ${h.link_to("View this {0}".format(model_title), action_url('view', instance))}
  • +
  • ${h.link_to("Back to {}".format(model_title_plural), url(route_prefix))}
  • + % if master.viewable and request.has_perm('{}.view'.format(permission_prefix)): +
  • ${h.link_to("View this {}".format(model_title), action_url('view', instance))}
  • % endif - % if master.deletable and request.has_perm('{0}.delete'.format(permission_prefix)): -
  • ${h.link_to("Delete this {0}".format(model_title), action_url('delete', instance))}
  • + % if master.deletable and master.deletable_instance(instance) and request.has_perm('{}.delete'.format(permission_prefix)): +
  • ${h.link_to("Delete this {}".format(model_title), action_url('delete', instance))}
  • + % endif + % if master.creatable and request.has_perm('{}.create'.format(permission_prefix)): +
  • ${h.link_to("Create a new {}".format(model_title), url('{}.create'.format(route_prefix)))}
  • % endif diff --git a/tailbone/templates/master/view.mako b/tailbone/templates/master/view.mako index 25520036..d20faa37 100644 --- a/tailbone/templates/master/view.mako +++ b/tailbone/templates/master/view.mako @@ -4,12 +4,15 @@ <%def name="title()">${model_title}: ${instance_title} <%def name="context_menu_items()"> -
  • ${h.link_to("Back to {0}".format(model_title_plural), url(route_prefix))}
  • - % if master.editable and request.has_perm('{0}.edit'.format(permission_prefix)): -
  • ${h.link_to("Edit this {0}".format(model_title), action_url('edit', instance))}
  • +
  • ${h.link_to("Back to {}".format(model_title_plural), url(route_prefix))}
  • + % if master.editable and request.has_perm('{}.edit'.format(permission_prefix)): +
  • ${h.link_to("Edit this {}".format(model_title), action_url('edit', instance))}
  • % endif - % if master.deletable and master.deletable_instance(instance) and request.has_perm('{0}.delete'.format(permission_prefix)): -
  • ${h.link_to("Delete this {0}".format(model_title), action_url('delete', instance))}
  • + % if master.deletable and master.deletable_instance(instance) and request.has_perm('{}.delete'.format(permission_prefix)): +
  • ${h.link_to("Delete this {}".format(model_title), action_url('delete', instance))}
  • + % endif + % if master.creatable and request.has_perm('{}.create'.format(permission_prefix)): +
  • ${h.link_to("Create a new {}".format(model_title), url('{}.create'.format(route_prefix)))}
  • % endif diff --git a/tailbone/views/master.py b/tailbone/views/master.py index 8b60099c..3b94b2f0 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -33,7 +33,7 @@ from edbob.util import prettify import formalchemy from pyramid.renderers import get_renderer, render_to_response -from pyramid.httpexceptions import HTTPFound, HTTPNotFound +from pyramid.httpexceptions import HTTPException, HTTPFound, HTTPNotFound from tailbone import forms from tailbone.views import View @@ -148,16 +148,28 @@ class MasterView(View): self.deleting = True instance = self.get_instance() - # Let derived classes prep for (or cancel) deletion. - result = self.before_delete(instance) - if result is not None: - return result + if not self.deletable_instance(instance): + self.request.session.flash("Deletion is not permitted for {} {}".format( + self.get_model_title(), instance)) + return HTTPFound(location=self.get_action_url('view', instance)) - self.delete_instance(instance) - self.request.session.flash("{0} {1} has been deleted.".format( - self.get_model_title(), instance)) - return self.redirect(self.get_after_delete_url(instance)) + form = self.make_form(instance) + # TODO: Add better validation, ideally CSRF etc. + if self.request.method == 'POST': + + # Let derived classes prep for (or cancel) deletion. + result = self.before_delete(instance) + if isinstance(result, HTTPException): + return result + + self.delete_instance(instance) + self.request.session.flash("{} {} has been deleted.".format( + self.get_model_title(), instance)) + return self.redirect(self.get_after_delete_url(instance)) + + form.readonly = True + return self.render_to_response('delete', {'instance': instance, 'form': form}) ############################## # Core Stuff @@ -379,9 +391,14 @@ class MasterView(View): if self.editable: actions.append(self.make_action('edit', icon='pencil')) if self.deletable: - actions.append(self.make_action('delete', icon='trash')) + actions.append(self.make_action('delete', icon='trash', url=self.default_delete_url)) return actions + def default_delete_url(self, row): + if self.deletable_instance(row): + return self.request.route_url('{}.delete'.format(self.get_route_prefix()), + **self.get_action_route_kwargs(row)) + def make_action(self, key, **kwargs): """ Make a new :class:`GridAction` instance for the current grid.