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>
+
+<%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>
+
+<%def name="confirmation()">
+
+ Are you sure about this?
+
+ ${h.form(request.current_route_url())}
+
+ ${h.end_form()}
+%def>
+
+
+
+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>
<%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
%def>
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>
<%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
%def>
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.