Each row on a member’s Unread and Read notification screens has Read (or Unread) and Delete buttons. Each button is its own POST form to the screen’s canonical URL, with the action, the notification ID and BuddyPress’s own nonce for that action in the body:
<form method="post" action="/members/{member}/notifications/">
<input type="hidden" name="bp_localhero_notification_action" value="delete" />
<input type="hidden" name="notification_id" value="123" />
<input type="hidden" name="_wpnonce" value="…" />
<button type="submit" class="wp-element-button delete confirm bp-tooltip">Delete</button>
</form>
- Actions are
mark_read,mark_unreadanddelete, checked against core’s noncesbp_notification_mark_read_{id},bp_notification_mark_unread_{id}andbp_notification_delete_{id}. bp_localhero_theme_action_notification()handles the post onbp_actionsat priority 9, before core’s handlers, using core’s functions and access checks (bp_notifications_delete_notification(),bp_notifications_mark_notification()). It adds core’s success or error notice and redirects back to the screen with 303 See Other.- The Unread screen’s canonical URL is the notifications URL itself, without the
unreadslug; the Read screen’s is…/notifications/read/. - Templates call
bp_localhero_theme_notification_action_form( $action, $notification_id, $label, $class )to output a button. The bulk actions form after the table is unchanged.
Why not core’s links
Core’s single-notification handlers read the action, ID and nonce from $_GET, and their URLs include the unread slug, which is not canonical. Up to 0.1.41 the pack posted to those URLs as they were. That only worked through BuddyPress’s canonical redirect, which bp_redirect_canonical() skips whenever $_POST is not empty, so as soon as any script added a field to the form (LH Localforage adds tracking data to every POST form) nothing was deleted or marked. Posting to the canonical URL with everything in the body keeps state changes out of URLs and does not depend on that redirect.