Как отправлять HTML-форматированные письма с помощью функции wp_mail() в WordPress?
Есть ли action_hook или что-то подобное, что могло бы помочь мне достичь этого?
Я пытался добавить разметку в PHP переменную и просто отправил email с помощью функции wp_mail()
таким образом:
$email_to = 'someaddress@gmail.com';
$email_subject = 'Тема письма';
$email_body = "<html><body><h1>Привет, мир!</h1></body></html>";
$send_mail = wp_mail($email_to, $email_subject, $email_body);
Но оно отобразилось как обычный текст?
Есть идеи?

В качестве альтернативы вы можете указать заголовок Content-Type HTTP в параметре $headers:
$to = 'sendto@example.com';
$subject = 'Тема письма';
$body = 'Содержимое письма';
$headers = array('Content-Type: text/html; charset=UTF-8');
wp_mail( $to, $subject, $body, $headers );

Этот вариант работает лучше, так как add_filter иногда отображается как вложение. Спасибо, что поделились!

Это, как правило, лучший способ сделать это. Ответ выше может конфликтовать с другими плагинами и вызывать проблемы.

Из моего прочтения исходного кода wp_mail() следует, что заголовки не могут быть массивом, а должны быть в форме 'to: joe@domain.com'. Все еще пытаюсь это проверить, и я уступлю более опытным разработчикам, чтобы они проверили мою точность.

Тип контента по умолчанию — 'text/plain', который не позволяет использовать HTML. Однако вы можете установить тип контента письма с помощью фильтра 'wp_mail_content_type'.
// В functions.php темы или коде плагина:
function wpse27856_set_content_type(){
return "text/html";
}
add_filter( 'wp_mail_content_type','wpse27856_set_content_type' );
Теперь каждый раз, когда вызывается wp_mail
, будь то в вашем коде, коде WordPress, коде плагина или коде темы, MIME-тип будет установлен в text/html
. Если есть какие-либо вызовы wp_mail
, которые отправляют обычный текст, эти вызовы теперь могут сломаться. Так что будьте осторожны.

Хм, звучит полезно. Просто вопрос: есть ли какая-то особая причина, по которой вы назвали свою функцию wpse27856_set_content_type?

Нет, это просто уникальное имя, основанное на id этого конкретного вопроса. wpse = wp stackexchange, 27856 - это id вопроса в URL. Я делаю это, чтобы избежать потенциальных коллизий, если люди копируют/вставляют код отсюда.

Вы также можете просто включить Content-Type в заголовки вашего email. Посмотрите, как это делает плагин Notifly.

Должно ли письмо быть в формате .txt или .html? Я использую этот метод, но если посмотреть исходный код, это .txt файл, и встроенное изображение не обрабатывается.

@AlxVallejo если вы отправляете из файла, вам, вероятно, сначала нужно прочитать файл как строку.

Передача заголовков напрямую является более эффективным методом, чем добавление хука. -1

@Jeremy конечно, но прямая передача заголовков не всегда возможна, например, когда вызов wp_mail
выполняется не вашим кодом.

@Milo Вы правы, но для данного вопроса заголовки являются правильным ответом.

Это нарушит работу письма для сброса пароля, потому что ссылка для сброса обернута в <>.

Не нарушит ли это работу другого кода, который ожидает, что wp_mail
отправляет обычное текстовое письмо, а не HTML-письмо?

@SimonJosefKok, если я правильно понимаю этот баг-репорт, проблема с нарушением работы писем для сброса пароля решена начиная с WordPress 5.4. Похоже, они решили убрать угловые скобки из адреса электронной почты. https://core.trac.wordpress.org/ticket/23578#comment:24

Не забудьте удалить фильтр типа контента после использования функции wp_mail. Согласно принятому соглашению о наименовании, это следует сделать после выполнения wp_mail:
remove_filter( 'wp_mail_content_type','wpse27856_set_content_type' );
Ознакомьтесь с этим тикетом - Сброс content-type во избежание конфликтов -- http://core.trac.wordpress.org/ticket/23578

Еще один простой способ, которым я поделюсь ниже. Вы даже можете стилизовать тело письма по своему желанию. Возможно, это будет вам полезно.
$email_to = 'someaddress@gmail.com';
$email_subject = 'Тема письма';
// <<<EOD — это heredoc-синтаксис PHP
$email_body = <<<EOD
Это ваш новый <b style="color: red; font-style: italic;">пароль</b> : {$password}
EOD;
$headers = ['Content-Type: text/html; charset=UTF-8'];
$send_mail = wp_mail( $email_to, $email_subject, $email_body, $headers );
Подробнее о heredoc-синтаксисе PHP https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc

Используйте ob_start
, так как это позволит вам использовать переменные/функции WordPress, такие как bloginfo и другие.
Создайте PHP-файл и вставьте в него ваш HTML (при необходимости используйте переменные WordPress внутри этого файла).
Используйте следующий код:
$to = 'Email Address'; // Адрес электронной почты
$subject = 'Your Subject'; // Тема письма
ob_start();
include(get_stylesheet_directory() . '/email-template.php'); // Путь к файлу шаблона
$body = ob_get_contents();
ob_end_clean();
$headers = array('Content-Type: text/html; charset=UTF-8','From: Test <test@test.com>');
wp_mail( $to, $subject, $body, $headers );
Это позволит сохранить ваш код чистым, а благодаря ob_start
мы также сэкономим время на загрузке файла.
