1

Is there a way to change the content type for only the password reset email?

I have a custom HTML template for it, and have set wp_mail_content_type to text/html and am applying the template with a filter on retrieve_password_message. That all works fine and I get an HTML email for it, but I’m having a hard time figuring out where/how to reset wp_mail_content_type since I’m not actually calling wp_mail() anywhere.

Any help would be greatly appreciated.

EDIT - here’s the code I’m using.

This is the function that changes the content type:

function xxx_wp_email_content_type() {
    return 'text/html';
}
add_filter( 'wp_mail_content_type', 'xxx_wp_email_content_type' );

And here’s the function that changes the email itself:

function xxx_wp_retrieve_password_message( $content, $key ) {
    ob_start();

    $email_subject = xxx_wp_retrieve_password_title();

    include( 'templates/email_header.php' );
    include( 'templates/lost_password_email.php' );
    include( 'templates/email_footer.php' );

    $message = ob_get_contents();
    ob_end_clean();

    return $message;
}
add_filter( 'retrieve_password_message', 'xxx_wp_retrieve_password_message', 10, 2 );

Typically I’d add a remove_filter( 'wp_mail_content_type', 'xxx_wp_email_content_type' ); after a call to wp_mail(), but there isn’t one here.

  • Can you provide an example of your code and how you're using the filters? – phatskat Dec 8 '17 at 19:18
  • Did not quite follow. Why do you need to reset the wp_mail_content_type, is it because you want other emails to send as text only? – signal2013 Dec 8 '17 at 19:27
  • @signal2013 Yes, the only one I want to send as HTML is the password reset email. – jmock Dec 8 '17 at 21:35
  • @phatskat Code has been added. – jmock Dec 8 '17 at 21:45
1

I suspect you implemented the hook something like this:

function wp_set_html_mail_content_type() {
    return 'text/html';
}
add_filter( 'wp_mail_content_type', 'wp_set_html_mail_content_type' );

More info: https://codex.wordpress.org/Plugin_API/Filter_Reference/wp_mail_content_type

Did you need to reset the content type at a later point?


** UPDATE: try intercept it with a global variable:

function xxx_wp_email_content_type() {
    if($GLOBALS["use_html_content_type"]){
        return 'text/html';
    }else{
        return 'text/plain';
    }
}
add_filter( 'wp_mail_content_type', 'xxx_wp_email_content_type' );

function xxx_wp_retrieve_password_message( $content, $key ) {
    ob_start();

    $GLOBALS["use_html_content_type"] = TRUE;

    $email_subject = xxx_wp_retrieve_password_title();

    include( 'templates/email_header.php' );
    include( 'templates/lost_password_email.php' );
    include( 'templates/email_footer.php' );

    $message = ob_get_contents();
    ob_end_clean();

    return $message;
}
add_filter( 'retrieve_password_message', 'xxx_wp_retrieve_password_message', 10, 2 );
  • That’s correct... that’s how I’m doing it. The part I’m having trouble figuring out is how to reset it to text/plain since I don’t want the other emails sent as HTML because they don’t have line breaks, etc. when they are set to HTML. – jmock Dec 8 '17 at 21:38
  • Ok, you could try intercept it with a global variable... I updated the snippet above. – signal2013 Dec 8 '17 at 22:14
  • Thanks! It seems to be working during initial testing. I still need to test a bit more, but it’s looking good so far. – jmock Dec 8 '17 at 22:36
1

This way works for me without setting a $GLOBAL:

function xxx_wp_email_content_type() {
    return 'text/html';
}

function xxx_wp_retrieve_password_message( $content, $key ) {
    add_filter( 'wp_mail_content_type', 'xxx_wp_email_content_type' );

    ob_start();

    $email_subject = xxx_wp_retrieve_password_title();

    include( 'templates/email_header.php' );
    include( 'templates/lost_password_email.php' );
    include( 'templates/email_footer.php' );

    $message = ob_get_contents();
    ob_end_clean();

    return $message;
}
add_filter( 'retrieve_password_message', 'xxx_wp_retrieve_password_message', 10, 2 );
0

This doesn't technically answer the question - but more the question behind the question. The reason you might want to set the content type only for the password reset email is that setting all system emails to text/html will break the default password reset email.

I suggest using the retrieve_password_message filter in combination with the wp_mail_content_type filter to make the password reset email compatible with the HTML format:

<?php
// adding support for html emails
// this converts ALL wp_mail emails to HTML, which messes up the password reset
add_filter( 'wp_mail_content_type','squarecandy_set_content_type' );
function squarecandy_set_content_type() {
        return "text/html";
}

// add this filter too
// this will make the password reset email compatible with the HTML format
add_filter( 'retrieve_password_message', 'squarecandy_retrieve_password_message', 10, 1 );
function squarecandy_retrieve_password_message( $message ) {
    // Revise the message content to make it HTML email compatible
    $message = str_replace('<','',$message);
    $message = str_replace('>','',$message);
    $message = str_replace("\n",'<br>',$message);
    // make any additional modifications to the message here...
    return $message;
}

Otherwise, if you only want to set individual emails to text/html, the $GLOBALS method in the answer from @signal2013 also works, but might be better applied to target your custom email instead of to the default password reset email (leave this as the default text/plain).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.