Wagtail has a few ways to customise content that is shown in the various Wagtail modeladmin views.
Code Example
Step 1 - create a custom CreateView
- This will override the
get_context_data
method to provide the create_url
, we could do this simpler (the context already has access to the instance) but it is nice to be explicit.
- Override the
get_success_url
method to allow for a URL param of next
to be set, if that exists the next URL will be this instead of the default behaviour.
products/wagtail_hooks.py
from wagtail.contrib.modeladmin.views import CreateView
# ... other imports
class CustomCreateView(CreateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['create_url'] = self.create_url
return context
def get_success_url(self):
next = self.request.GET.get('next')
if next:
return next
return super().get_success_url()
class ProductsModelAdmin(ModelAdmin):
create_view_class = CustomCreateView
Step 2 - Override the template to add a new button
- Wagtail modeladmin uses a template path override approach, you will need to create a new template that aligns with your desired override (for example we may just want to override the product model create view only.
templates/modeladmin/products/products/create.html
-> this says to override the create template for the products model within the products app.
- Add the code below and check it is working, sometimes the templates path can be a bit tricky so ensure you can see the new button AND that the button has the
data-next
attribute that should be your create URL.
templates/modeladmin/products/products/create.html
{% extends "modeladmin/create.html" %}
{% load i18n wagtailadmin_tags %}
{% block form_actions %}
{{ block.super }}
<div class="dropdown dropup dropdown-button match-width">
<button type="submit" class="button button-secondary action-save button-longrunning" data-next="{{ create_url }}" data-clicked-text="{% trans 'Saving…' %}">
{% icon name="spinner" %}<em>{% trans 'Save & add another' %}</em>
</button>
</div>
{% endblock %}
Step 3 - Add JS to modify the form action URL on click
- The next step requires a bit of JavaScript, we want to attach a different behaviour to the 'save and add another' button.
- The JS used here does not require jQuery and should work in IE11
- Once the DOM is loaded (which means JS can do things), find all the buttons with the
data-next
attribute.
- Add a listener to the 'click' of each of those buttons which will dynamically update the form
action
attribute with the extra URL part.
- This extra URL part gets read by the
get_success_url
method in the custom create class but only on a successful save, otherwise you will stay on the page and be able to fix errors.
{% block extra_js %}
{{ block.super}}
<script>
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('[data-next]').forEach(function(button) {
button.addEventListener('click', function(event) {
var form = document.querySelector('.content-wrapper form');
form.action = form.action + '?next=' + button.dataset.next;
});
});
})
</script>
{% endblock %}