Nice Default Emails
How Adminkeep's Nice Default Emails works: the 25 WordPress core emails it wraps in HTML, what the layout holds, what is left alone, the filter and WP-CLI.
Nice Default Emails sends the plain-text emails WordPress itself writes, such as password resets, new-user notices and comment notifications, in a simple HTML layout with your site’s name on it. The text is unchanged; it gets a header, a card and a footer. This page is the reference; the Nice Default Emails page has the overview.
Turn it on
Go to Settings → Adminkeep and switch on Nice Default Emails, in the Email group. There are no settings: one layout, coloured and named from the site. From then on, each of the emails below goes out as HTML.
Nothing is stored. Switch the feature off and the next email goes out as plain text again.
The emails it covers
25 emails: 19 on a single site, and 6 more that exist only on a multisite network. The id in the first column is what the filter and the WP-CLI commands call each one.
Accounts
| Id | |
|---|---|
password_reset | Password reset link |
new_user | New account: login details, to the user |
new_user_admin | New account: notice to the site admin |
password_changed | Password changed, to the user |
password_changed_admin | Password changed, to the site admin |
email_changed | Account email changed, to the old address |
email_change_request | Confirm a new account email |
admin_email_change_request | Confirm a new site admin email |
admin_email_changed | Site admin email changed, to the old address |
Comments
| Id | |
|---|---|
comment_notification | New comment, to the post author |
comment_moderation | Comment awaiting moderation |
Updates and site health
| Id | |
|---|---|
core_update | WordPress updated automatically |
plugin_theme_update | Plugins or themes updated automatically |
update_debug | Automatic update debug report |
recovery_mode | Technical issue (recovery mode) notice |
Privacy
| Id | |
|---|---|
privacy_request | Personal data request: confirm |
privacy_request_confirmed | Personal data request confirmed, to the site admin |
privacy_export_ready | Personal data export ready |
privacy_erasure_done | Personal data erased |
Multisite only
| Id | |
|---|---|
signup_site | Activate a new site |
signup_user | Activate a new account |
welcome_site | New site welcome |
welcome_user | New account welcome |
network_admin_email_change_request | Confirm a new network admin email |
network_admin_email_changed | Network admin email changed |
What is left alone
- Every other plugin’s email. WooCommerce order emails, form notifications, membership and newsletter plugins: none of them are touched, HTML or plain text.
- Anything already sent as HTML or multipart, whoever sends it. An email that declares a
content type other than
text/plainis not asked about, whatever the filter below says. - A core email another plugin has changed in its own
wp_mailfilter. The feature recognises an email by the text WordPress settled on. If another plugin then changes that text in awp_mailfilter, the email no longer matches and goes out as that plugin left it. Changes made through WordPress’s own per-email filters, such asretrieve_password_notification_email, are fine: the feature reads the text after them.
When in doubt, nothing is touched: an email the feature cannot identify is sent as it was.
How an email is recognised
WordPress passes each of its emails through a filter of its own just before sending, such as
retrieve_password_notification_email or comment_notification_text. Nice Default Emails
listens on each of those, last, and notes the text WordPress settled on. When wp_mail() is
then called with that same text, and the email is plain text, the layout is applied. Placeholders
WordPress fills in between the filter and the send are allowed for.
That is why the feature does not guess from subjects, which are translated and filterable, and why it does not sweep up every plain-text email on the site.
The layout
- Header: your site’s name, linking to the home page. A site with no name is called by its host instead.
- Card: the text WordPress wrote, unchanged. Line breaks are kept and web addresses become links, so a reset or confirmation link still works. Text is escaped first, so nothing in an email is read as markup.
- Footer: the site’s name and its address, linking home.
The template is built for mail clients rather than browsers: tables, every style inline, no web
fonts and no images. Colours are WordPress admin’s own (near-black text, admin-blue links, a light
grey page). Mail clients that respect prefers-color-scheme get a dark version; clients that drop
the style block, as Gmail does, show the light one. The email’s language and direction follow the
site’s.
The Content-Type header is swapped for text/html with the site’s charset; every other header
is kept as it was.
With SMTP and Email Log
The layout is applied on the wp_mail filter, after ordinary filters and before the email reaches
the mailer, so it goes out the same way with Adminkeep’s SMTP
feature, with another SMTP plugin, or with no SMTP setup at all.
With Email Log on, the log records the HTML version, which is what was sent, and the preview renders it as a mail client would. Sign-in and reset links are still removed before the email is stored, as for any other email.
For developers
One filter decides whether an email gets the layout:
/**
* @param bool $wrap True for one of WordPress core's own emails, false otherwise.
* @param string $email_id The email's id (see the tables above), or '' when it is not one of core's.
* @param array $atts wp_mail() arguments: to, subject, message, headers, attachments.
*/
add_filter( 'adminkeep_nice_emails_wrap', function ( $wrap, $email_id, $atts ) {
// Keep the comment moderation email plain.
if ( 'comment_moderation' === $email_id ) {
return false;
}
// Give a plain-text email of your own the same layout.
if ( 'Weekly digest' === $atts['subject'] ) {
return true;
}
return $wrap;
}, 10, 3 );
The filter is not asked about an email that already declares HTML or multipart content; those are left alone regardless. If the template cannot be built for an email, that email goes out as plain text rather than not at all.
WP-CLI
Most of these emails are hard to trigger on purpose, so the plugin can send them for you:
wp adminkeep feature enable nice_emails
wp adminkeep emails list
wp adminkeep emails send password_reset [email protected]
wp adminkeep emails send --all [email protected]
| Command | What it does |
|---|---|
wp adminkeep emails list | The core emails this site can send, with the function that sends each |
wp adminkeep emails send <id>... --to=<email> | Sends the named emails to one address |
wp adminkeep emails send --all --to=<email> | Sends every one of them |
send makes WordPress send each email through the function that sends it for real, so it arrives
exactly as your site would send it: through your mailer, in the layout, and recorded by Email Log
when that is on. Only the recipient is changed; every email goes to --to and to nobody else.
What an email needs is created for the run and deleted after it (a throwaway subscriber, a
private post with two comments, personal data requests), and settings WordPress writes while
sending are put back, so the links in those emails do nothing. It needs Nice Default Emails
switched on, and exits 1 if any email fails.
The full reference is Core emails in the WP-CLI docs, and
wp help adminkeep emails matches the version you run.