Laravel override mail to automatically add plain text version

谁都会走 提交于 2021-01-04 07:33:59

问题


I'm making some changes in my Laravel app to automatically add plain text version to my e-mails.. I'm doing that by using the library

https://packagist.org/packages/html2text/html2text

I would get the text version by running

\Html2Text\Html2Text::convert($content)

Now I want to override laravels Mailable.php buildView() function to automaticaly generate the text. My question is: how to properly override it? Where can I redeclare it?


回答1:


The Mailer is defined by the Mailer Service Provider, you can see the registration of it in your config/app.php under 'providers', where you will see this:

\Illuminate\Mail\MailServiceProvider::class,

So, all you need to do, is remove the MailServiceProvider registration and create your own Provider based on that one with your changes and register yours.

Make sure you implement the Illuminate\Contracts\Mail\Mailer contract.

But you don't need to!

The mailer that comes with Laravel already support sending the HTML and Plain versions of your email.

The Mailer::send() method's first argument is @param string|array $view, where you usually send the view name of the HTML version of your email, but, you can instead send an array like this...

Mailer::send([
    'html' => 'my-mails.notification-in-html',
    'text' => 'my-mails.notification-in-text',
  ], $data, $callback);

Where you could even define a different text and remove things that you would not put in your plain text version, or adjust a different signature that looks good on plain, and also format things different.

For more information you can look at the parseView() in Illuminate\Mail\Mailer class.

So, there you have it, 2 options:

  • Create your own Mailer and register it instead of the default one
  • or just call the mailer with an array of views.



回答2:


When I was needed to use the same HTML template for plain text version, I've overriden the Mailable in the following way:

<?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;
    }
}

And then in child Mailable you can use it like view() method before:

<?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,
            ]);
    }
}

And in templates you'll have $plain=true variable for Plain Text emails so you can re-use HTML template files for plain text with

@if (empty($plain))
<div>Some HTML content</div>
@else
Some plain text content
@endif


来源:https://stackoverflow.com/questions/39429422/laravel-override-mail-to-automatically-add-plain-text-version

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!