Pergunta

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.

Foi útil?

Solução

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 );

Outras dicas

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 );

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).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a wordpress.stackexchange
scroll top