-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Access to request object in register_user_listing_buttons
#11915
Comments
The change happened in #11823 |
Thanks for the report, and sorry for the trouble! Here's my investigation results. RationaleThe idea was that I wanted to allow the wagtail/wagtail/admin/views/generic/models.py Line 375 in 538365f
Then, the custom view subclass would be specified in the custom viewset. This would align better with how we're moving towards the viewsets being the one place to configure your views, instead of individual hooks. It also encourages working with the view directly to do any logic instead of treating the Another reason is that, none of the other In the future, I'm imagining a dedicated/expanded section in the Wagtail docs on how to work with and customise Wagtail's generic views and viewsets, so that it includes things like customising the listing view buttons, and the header buttons (the ones you see in the breadcrumbs). Ideally, the guide would be applicable to all views that are customisable, including Unfortunately, we were short on time and I didn't get to implement the ability to customise the
With the move towards using The preferred way would be to pass anything you need in the button directly to the button's constructor, which makes it more explicit compared to accessing the context (which may or may not have what you want, e.g. due to the use of Reinstating support for the given customisationAnyway... back to the issue at hand. I couldn't get the provided example to work as expected in 6.0.x nor 5.2.x. Which version was the latest where this still worked @tomusher? To make it work, I had to change class HijackFormButton(UserListingButton):
def __init__(self, *, user_pk, request):
self.user_pk = user_pk
self.request = request
super().__init__(
"Impersonate",
None,
priority=10,
)
def render_html(self, parent_context):
csrf_token = get_token(self.request)
return mark_safe(
f"""
<form method="POST" action="{reverse("hijack:acquire")}">
<input type="hidden" name="csrfmiddlewaretoken" value="{csrf_token}">
<input type="hidden" name="user_pk" value="{self.user_pk}">
<button class="button button-secondary button-small" title="Login as this user">{self.label}</button>
</form>
"""
)
@hooks.register("register_user_listing_buttons")
def user_listing_hijack_button(context, user):
yield HijackFormButton(
user_pk=user.pk,
request=context.request,
) After the above changes, the hook works as expected on 5.2.x and 6.0.x. With that out of the way, there are a few things that unfortunately make it tricky to fix this in a 6.1.x patch release with minimal impact. I'll separate this into two steps. 1. Ensuring each button can define how it can render itselfThe wagtail/wagtail/admin/widgets/button.py Lines 170 to 171 in 8aaa579
wagtail/wagtail/admin/templates/wagtailadmin/pages/listing/_button_with_dropdown.html Line 3 in 8aaa579
wagtail/wagtail/admin/templates/wagtailadmin/pages/listing/_dropdown_items.html Lines 3 to 10 in 8aaa579
This means that the We need to fix this if we want to allow a button to have its own markup. This potentially affects the page listing buttons too, so I'd be wary to do it in a patch release. Might be OK if we're extra careful, though. 2. Passing the requestThe hook is now called in the view before the context is finalised by wagtail/wagtail/users/views/users.py Lines 200 to 236 in 8aec935
As such, we're no longer able to give the full context to the hook. However, we can still include the This means that with the fix for (1), the customisation will continue to work using the old hook signature (since If we want to use the new signature for the hook, we can't retrieve the wagtail/wagtail/admin/widgets/button.py Lines 180 to 187 in 8aaa579
Option A: pass the request via
|
Is your proposal related to a problem?
In Wagtail 6.1, the
register_user_listing_buttons
hook signature changed to remove thecontext
.In migrating one of my sites to 6.1, I realised that one of the the buttons I add to the user listing is an 'Impersonate' button, making use of
django-hijack
to impersonate a specific user.This button is implemented like:
Where the
request
object is used to generate a CSRF token for the form submission.With the new hook signature, I don't have a clean way to make the
request
object available to the button.I'm wondering what the justification for removing access to the
request
was, and whether there's any reason it couldn't be added back?Describe the solution you'd like
Adding a
request
parameter to theregister_user_listing_buttons
hook.Alternatively, a hook for adding a common context to all buttons might be useful - in the above example this could be used to generate a single CSRF token that could be reused between instances, and may be useful for performance optimisations in cases where buttons need to retrieve additional data.
Working on this
I'm happy to work on this once I understand the reason it was removed in the first place to avoid repeating or reintroducing any issues that this caused.
The text was updated successfully, but these errors were encountered: