Nice Default Emails

View as Markdown

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

IdEmail
password_resetPassword reset link
new_userNew account: login details, to the user
new_user_adminNew account: notice to the site admin
password_changedPassword changed, to the user
password_changed_adminPassword changed, to the site admin
email_changedAccount email changed, to the old address
email_change_requestConfirm a new account email
admin_email_change_requestConfirm a new site admin email
admin_email_changedSite admin email changed, to the old address

Comments

IdEmail
comment_notificationNew comment, to the post author
comment_moderationComment awaiting moderation

Updates and site health

IdEmail
core_updateWordPress updated automatically
plugin_theme_updatePlugins or themes updated automatically
update_debugAutomatic update debug report
recovery_modeTechnical issue (recovery mode) notice

Privacy

IdEmail
privacy_requestPersonal data request: confirm
privacy_request_confirmedPersonal data request confirmed, to the site admin
privacy_export_readyPersonal data export ready
privacy_erasure_donePersonal data erased

Multisite only

IdEmail
signup_siteActivate a new site
signup_userActivate a new account
welcome_siteNew site welcome
welcome_userNew account welcome
network_admin_email_change_requestConfirm a new network admin email
network_admin_email_changedNetwork 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/plain is not asked about, whatever the filter below says.
  • A core email another plugin has changed in its own wp_mail filter. The feature recognises an email by the text WordPress settled on. If another plugin then changes that text in a wp_mail filter, the email no longer matches and goes out as that plugin left it. Changes made through WordPress’s own per-email filters, such as retrieve_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]
CommandWhat it does
wp adminkeep emails listThe 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.

Switch on what you need. Forget the rest.

A free WordPress plugin — GPL, instantly reversible, and updates come to you.

Type to search the whole site.