Laravel覆盖邮件自动添加纯文本版本
Laravel override mail to automatically add plain text version
我正在对我的 Laravel 应用程序进行一些更改,以自动将纯文本版本添加到我的电子邮件中。我正在通过使用库来做到这一点
https://packagist.org/packages/html2text/html2text
我会通过 运行
获得文本版本
\Html2Text\Html2Text::convert($content)
现在我想覆盖 laravels Mailable.php buildView() 函数来自动生成文本。我的问题是:如何正确覆盖它?我可以在哪里重新申报?
Mailer 是由 Mailer Service Provider 定义的,您可以在 'providers'
下的 config/app.php
中看到它的注册,在那里您会看到:
\Illuminate\Mail\MailServiceProvider::class,
因此,您需要做的就是删除 MailServiceProvider 注册并根据您的更改创建您自己的提供程序并注册您的。
确保执行 Illuminate\Contracts\Mail\Mailer
合同。
但你不需要!
Laravel 附带的邮件程序已经支持发送电子邮件的 HTML 和普通版本。
Mailer::send()
方法的第一个参数是 @param string|array $view
,您通常会在其中发送电子邮件的 HTML 版本的视图名称,但是,您也可以发送这样的数组...
Mailer::send([
'html' => 'my-mails.notification-in-html',
'text' => 'my-mails.notification-in-text',
], $data, $callback);
您甚至可以定义不同的文本并删除您不会放入纯文本版本的内容,或者调整在纯文本中看起来不错的不同签名,还可以设置不同的格式。
有关详细信息,您可以查看 Illuminate\Mail\Mailer
class 中的 parseView()
。
所以,你有它,2 个选项:
- 创建您自己的 Mailer 并注册它而不是默认的
- 或者只调用带有视图数组的邮件程序。
当我需要为纯文本版本使用相同的 HTML 模板时,我按以下方式覆盖了 Mailable:
<?php
namespace App\Mail;
// [...] some other imports
use Illuminate\Mail\Mailable;
class BaseMailable extends Mailable
{
// [...] some other code
/**
* Method to add plain text version by converting it from HTML version
* Separate plain text view could be used if exists
*/
public function viewHtmlWithPlainText($view, array $data = [])
{
// NOTE: we render HTML separately because HTML and Plain versions have the same data
// and we need to pass `plain` parameter to the HTML template to render it differently
$this->html( view($view, $this->buildViewData())->render() );
$plainTextView = str_replace('emails.', 'emails.txt.', $view);
$plainTextAttrs = [
'plain' => true,
'senderName' => config('app.name')
];
if (view()->exists($plainTextView)) {
$this->text( $plainTextView, array_merge($plainTextAttrs, $data) );
} else {
$this->text( $view, array_merge($plainTextAttrs, $data) );
}
return $this;
}
}
然后在子 Mailable 中,您可以像之前的 view()
方法一样使用它:
<?php
namespace App\Mail;
use App\Mail\BaseMailable;
class UserResetPasswordLink extends BaseMailable
{
public function build()
{
return $this
->subject(trans('ui.reset_password'))
->viewHtmlWithPlainText('emails.client.user-reset-password-link', [
'token' => $this->token,
]);
}
}
并且在模板中,您将拥有用于纯文本电子邮件的 $plain=true
变量,因此您可以 re-use HTML 纯文本模板文件
@if (empty($plain))
<div>Some HTML content</div>
@else
Some plain text content
@endif
我正在对我的 Laravel 应用程序进行一些更改,以自动将纯文本版本添加到我的电子邮件中。我正在通过使用库来做到这一点
https://packagist.org/packages/html2text/html2text
我会通过 运行
获得文本版本\Html2Text\Html2Text::convert($content)
现在我想覆盖 laravels Mailable.php buildView() 函数来自动生成文本。我的问题是:如何正确覆盖它?我可以在哪里重新申报?
Mailer 是由 Mailer Service Provider 定义的,您可以在 'providers'
下的 config/app.php
中看到它的注册,在那里您会看到:
\Illuminate\Mail\MailServiceProvider::class,
因此,您需要做的就是删除 MailServiceProvider 注册并根据您的更改创建您自己的提供程序并注册您的。
确保执行 Illuminate\Contracts\Mail\Mailer
合同。
但你不需要!
Laravel 附带的邮件程序已经支持发送电子邮件的 HTML 和普通版本。
Mailer::send()
方法的第一个参数是 @param string|array $view
,您通常会在其中发送电子邮件的 HTML 版本的视图名称,但是,您也可以发送这样的数组...
Mailer::send([
'html' => 'my-mails.notification-in-html',
'text' => 'my-mails.notification-in-text',
], $data, $callback);
您甚至可以定义不同的文本并删除您不会放入纯文本版本的内容,或者调整在纯文本中看起来不错的不同签名,还可以设置不同的格式。
有关详细信息,您可以查看 Illuminate\Mail\Mailer
class 中的 parseView()
。
所以,你有它,2 个选项:
- 创建您自己的 Mailer 并注册它而不是默认的
- 或者只调用带有视图数组的邮件程序。
当我需要为纯文本版本使用相同的 HTML 模板时,我按以下方式覆盖了 Mailable:
<?php
namespace App\Mail;
// [...] some other imports
use Illuminate\Mail\Mailable;
class BaseMailable extends Mailable
{
// [...] some other code
/**
* Method to add plain text version by converting it from HTML version
* Separate plain text view could be used if exists
*/
public function viewHtmlWithPlainText($view, array $data = [])
{
// NOTE: we render HTML separately because HTML and Plain versions have the same data
// and we need to pass `plain` parameter to the HTML template to render it differently
$this->html( view($view, $this->buildViewData())->render() );
$plainTextView = str_replace('emails.', 'emails.txt.', $view);
$plainTextAttrs = [
'plain' => true,
'senderName' => config('app.name')
];
if (view()->exists($plainTextView)) {
$this->text( $plainTextView, array_merge($plainTextAttrs, $data) );
} else {
$this->text( $view, array_merge($plainTextAttrs, $data) );
}
return $this;
}
}
然后在子 Mailable 中,您可以像之前的 view()
方法一样使用它:
<?php
namespace App\Mail;
use App\Mail\BaseMailable;
class UserResetPasswordLink extends BaseMailable
{
public function build()
{
return $this
->subject(trans('ui.reset_password'))
->viewHtmlWithPlainText('emails.client.user-reset-password-link', [
'token' => $this->token,
]);
}
}
并且在模板中,您将拥有用于纯文本电子邮件的 $plain=true
变量,因此您可以 re-use HTML 纯文本模板文件
@if (empty($plain))
<div>Some HTML content</div>
@else
Some plain text content
@endif