@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/portfolio/lh-buddypress-template-pack/>
  a sioc:Post ;
  dc:title "Notification actions" ;
  dcterms:identifier 153125 ;
  dc:modified "2026-11-02T01:34:08Z"^^xsd:dateTime ;
  dc:created "2026-11-02T01:34:08Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-buddypress-template-pack/notification-actions/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded """<ul class="lh_portfolio-meta"><li><strong>Part of:</strong> <a href="https://lhero.org/portfolio/lh-buddypress-template-pack/">LH BuddyPress Template Pack</a></li></ul>
<p class="wp-block-paragraph">Each row on a member&#8217;s Unread and Read notification screens has Read (or Unread) and Delete buttons. Each button is its own POST form to the screen&#8217;s canonical URL, with the action, the notification ID and BuddyPress&#8217;s own nonce for that action in the body:</p>



<pre class="wp-block-code"><code>&lt;form method="post" action="/members/{member}/notifications/"&gt;
  &lt;input type="hidden" name="bp_localhero_notification_action" value="delete" /&gt;
  &lt;input type="hidden" name="notification_id" value="123" /&gt;
  &lt;input type="hidden" name="_wpnonce" value="…" /&gt;
  &lt;button type="submit" class="wp-element-button delete confirm bp-tooltip"&gt;Delete&lt;/button&gt;
&lt;/form&gt;</code></pre>



<ul class="wp-block-list">
<li>Actions are <code>mark_read</code>, <code>mark_unread</code> and <code>delete</code>, checked against core&#8217;s nonces <code>bp_notification_mark_read_{id}</code>, <code>bp_notification_mark_unread_{id}</code> and <code>bp_notification_delete_{id}</code>.</li>



<li><code>bp_localhero_theme_action_notification()</code> handles the post on <code>bp_actions</code> at priority 9, before core&#8217;s handlers, using core&#8217;s functions and access checks (<code>bp_notifications_delete_notification()</code>, <code>bp_notifications_mark_notification()</code>). It adds core&#8217;s success or error notice and redirects back to the screen with 303 See Other.</li>



<li>The Unread screen&#8217;s canonical URL is the notifications URL itself, without the <code>unread</code> slug; the Read screen&#8217;s is <code>…/notifications/read/</code>.</li>



<li>Templates call <code>bp_localhero_theme_notification_action_form( $action, $notification_id, $label, $class )</code> to output a button. The bulk actions form after the table is unchanged.</li>
</ul>



<h2 class="wp-block-heading">Why not core&#8217;s links</h2>



<p class="wp-block-paragraph">Core&#8217;s single-notification handlers read the action, ID and nonce from <code>$_GET</code>, and their URLs include the <code>unread</code> slug, which is not canonical. Up to 0.1.41 the pack posted to those URLs as they were. That only worked through BuddyPress&#8217;s canonical redirect, which <code>bp_redirect_canonical()</code> skips whenever <code>$_POST</code> 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.</p>
"""^^rdf:XMLLiteral ;
  sioc:content """Part of: LH BuddyPress Template Pack
Each row on a member&#8217;s Unread and Read notification screens has Read (or Unread) and Delete buttons. Each button is its own POST form to the screen&#8217;s canonical URL, with the action, the notification ID and BuddyPress&#8217;s own nonce for that action in the body:



&lt;form method="post" action="/members/{member}/notifications/"&gt;
  &lt;input type="hidden" name="bp_localhero_notification_action" value="delete" /&gt;
  &lt;input type="hidden" name="notification_id" value="123" /&gt;
  &lt;input type="hidden" name="_wpnonce" value="…" /&gt;
  &lt;button type="submit" class="wp-element-button delete confirm bp-tooltip"&gt;Delete&lt;/button&gt;
&lt;/form&gt;




Actions are mark_read, mark_unread and delete, checked against core&#8217;s nonces bp_notification_mark_read_{id}, bp_notification_mark_unread_{id} and bp_notification_delete_{id}.



bp_localhero_theme_action_notification() handles the post on bp_actions at priority 9, before core&#8217;s handlers, using core&#8217;s functions and access checks (bp_notifications_delete_notification(), bp_notifications_mark_notification()). It adds core&#8217;s success or error notice and redirects back to the screen with 303 See Other.



The Unread screen&#8217;s canonical URL is the notifications URL itself, without the unread slug; the Read screen&#8217;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&#8217;s links



Core&#8217;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&#8217;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.
""" ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1>, <https://lhero.org/?taxonomy=lh_object_key&term=lh-portfolio_doc_20261101t143500-notification-actions> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=lh_object_key&term=lh-portfolio_doc_20261101t143500-notification-actions> rdfs:seeAlso <https://lhero.org/?taxonomy=lh_object_key&term=lh-portfolio_doc_20261101t143500-notification-actions&feed=lhrdf&format=turtle> .
