Emails
WB Member Blog and WB Member Blog Pro send 17 emails between them. Every one works out of the box with no configuration — subjects, headings, the site name and every link are built from your site’s own settings — and every one can be changed without forking a plugin.
There is no email settings screen. Everything here is done in code, from a theme or a small plugin.
The 17 emails
Section titled “The 17 emails”Each has a stable id. That id is what you filter on, and what you name a template file after.
| ID | Sent to | When |
|---|---|---|
digest |
Follower | A periodic round-up of new posts from writers and topics they follow |
follow_new_post |
Follower | A writer they follow publishes |
clap |
Author | A reader claps for their post |
Pro — moderation
Section titled “Pro — moderation”| ID | Sent to | When |
|---|---|---|
admin_pending_review |
Administrators | A member submits a post for review |
post_published |
Author | Their post is approved and published |
post_rejected |
Author | A reviewer sends the post back |
Pro — engagement
Section titled “Pro — engagement”| ID | Sent to | When |
|---|---|---|
new_comment |
Author | Someone comments on their post |
post_reaction |
Author | Someone reacts (with the Reactions plugin active) |
post_milestone |
Author | A post passes a view threshold |
Pro — co-authors
Section titled “Pro — co-authors”| ID | Sent to | When |
|---|---|---|
coauthor_invited |
Invitee | An author invites them onto a post |
coauthor_accepted |
Inviter | The invitee accepts |
coauthor_declined |
Inviter | The invitee declines |
coauthor_approved |
Co-authors | The post is approved |
coauthor_revision |
Co-authors | A reviewer asks for changes |
coauthor_published |
Co-authors | The post goes live |
Pro — scheduling
Section titled “Pro — scheduling”| ID | Sent to | When |
|---|---|---|
scheduled_published |
Author | A scheduled post publishes |
scheduled_blocked |
Author | A scheduled post is blocked at publish time |
To read the list in code, including labels and the placeholders each supports:
$emails = \Wbcom\MemberBlog\Services\EmailRegistry::all();Turning one off
Section titled “Turning one off”add_filter( 'bpmb_email_enabled', function ( $enabled, $id ) { // Silence clap notifications, leave the other sixteen alone. return 'clap' === $id ? false : $enabled;}, 10, 2 );This is the plugin-level switch. Members still have their own notification preferences, which are checked separately — turning an email off here overrides both.
Changing a subject
Section titled “Changing a subject”add_filter( 'bpmb_email_subject', function ( $subject, $id ) { if ( 'post_rejected' === $id ) { return sprintf( __( '%s: your draft needs another look', 'your-textdomain' ), get_bloginfo( 'name' ) ); } return $subject;}, 10, 2 );Changing a body
Section titled “Changing a body”add_filter( 'bpmb_email_body', function ( $message, $id ) { if ( 'clap' !== $id ) { return $message; }
// $message is either a string, or the template's argument array. return array( 'heading' => __( 'Someone liked your writing', 'your-textdomain' ), 'body' => array( __( 'Keep going — people are reading.', 'your-textdomain' ) ), 'button' => array( 'label' => __( 'See your posts', 'your-textdomain' ), 'url' => home_url( '/my-blog-dashboard/' ), ), );}, 10, 2 );Supported keys: preheader, greeting, heading, body (string or array of paragraphs), button (label, url), note, footer.
Replacing a whole message with a template file
Section titled “Replacing a whole message with a template file”Drop a file in your theme, named after the email id:
yourtheme/buddypress-member-blog/emails/post_rejected.phpIt is looked up in the child theme first, then the parent, then the plugin’s own templates/emails/. Whatever it echoes becomes the message body, still wrapped in the shared frame.
<?phpdefined( 'ABSPATH' ) || exit;
// $bpmb_email holds: to, subject, messageprintf( '<p>%s</p>', esc_html__( 'Your draft needs a small change before we can publish it.', 'your-textdomain' ));To find the resolved path (useful when debugging which file is winning):
\Wbcom\MemberBlog\Services\EmailRegistry::locate_template( 'post_rejected' );Restyling every email at once
Section titled “Restyling every email at once”The shared frame draws its colours from one filterable palette, so a single filter rebrands all 17:
add_filter( 'bpmb_email_palette', function ( $palette ) { $palette['accent'] = '#8b5cf6'; $palette['button'] = '#8b5cf6'; return $palette;} );Keys: accent, ink, muted, rule, paper, canvas, button, on_dark.
The frame uses tables and inline styles on purpose — Outlook’s rendering engine has neither flexbox nor grid, and no email client can be relied on for CSS custom properties. That is why the palette is resolved to literal hex here rather than reusing the --bpmb-* variables the screen styles use.
Sending your own
Section titled “Sending your own”bpmb_mail()::dispatch( $user->user_email, __( 'Something happened', 'your-textdomain' ), array( 'heading' => __( 'Something happened', 'your-textdomain' ), 'body' => array( __( 'Here are the details.', 'your-textdomain' ) ), ), array(), 'your_email_id' // Optional. Register it via `bpmb_emails` to make it filterable.);One recipient sends immediately. For many, use dispatch_bulk() (one body, many recipients) or dispatch_each() (a personalised body per recipient) — both queue and drain on cron, so a fan-out never blocks the request the member is waiting on.
The plain-text alternative is generated from the same content automatically. You do not write it twice.

