spatie/laravel-database-mail-templates

使用数据库中存储的模板渲染 Laravel 可邮寄邮件。

3.6.0 2024-04-02 05:57 UTC

This package is auto-updated.

Last update: 2024-09-04 11:53:19 UTC


README

Latest Version on Packagist Test Status PHP CS Fixer Status Total Downloads

使用数据库中存储的模板渲染 Laravel 可邮寄邮件。

支持我们

我们投入了大量资源来创建 一流的开放源代码包。您可以通过 购买我们的付费产品之一 来支持我们。

我们非常感谢您从家乡寄给我们明信片,并说明您正在使用我们的哪些包。您可以在 我们的联系页面 上找到我们的地址。我们将发布所有收到的明信片在我们的 虚拟明信片墙上

快速示例

以下示例将使用存储在数据库中的模板和包装在 HTML 布局中的模板发送 WelcomeMail

namespace App\Mail;

use Spatie\MailTemplates\TemplateMailable;

class WelcomeMail extends TemplateMailable
{
    /** @var string */
    public $name;

    public function __construct(User $user)
    {
        $this->name = $user->name;
    }
    
    public function getHtmlLayout(): string
    {
        $pathToLayout = storage_path('mail-layouts/main.html');
    
        return file_get_contents($pathToLayout);
    }
}

MailTemplate::create([
    'mailable' => \App\Mail\WelcomeMail::class,
    'subject' => 'Welcome, {{ name }}',
    'html_template' => '<p>Hello, {{ name }}.</p>',
    'text_template' => 'Hello, {{ name }}.'
]);

Mail::to($user->email)->send(new WelcomeMail($user));

发送的电子邮件的 HTML 将看起来像这样

<header>Welcome!</header>
<p>Hello, John.</p>
<footer>Copyright 2018</footer>

安装

您可以通过 composer 安装此包

composer require spatie/laravel-database-mail-templates

发布并运行数据库迁移

php artisan vendor:publish --provider="Spatie\MailTemplates\MailTemplatesServiceProvider" --tag="migrations"

如果您想使用 默认的 MailTemplate 模型,剩下的只是运行 php artisan migrate 来创建 mail_templates 表。

如果您计划创建 自定义的 MailTemplate 模型,请继续修改迁移并在运行 php artisan migrate 之前创建您的自定义模型。

使用方法

安装包并运行迁移后,您将在数据库中有一个名为 mail_templates 的新表。此表将由 MailTemplate 模型使用。

默认的 MailTemplate 有一个 mailable 属性,它与 Mailable 的类名相对应。它还有一个 subjectbody 属性,这两个属性都用于存储 mustache 模板 字符串。

您可能需要设置一个生成器,以便为应用程序生成必要的模板

use Illuminate\Database\Seeder;

class MailTemplatesSeeder extends Seeder
{
    public function run()
    {
        MailTemplate::create([
            'mailable' => \App\Mail\WelcomeMail::class,
            'subject' => 'Welcome, {{ name }}',
            'html_template' => '<h1>Hello, {{ name }}!</h1>',
            'text_template' => 'Hello, {{ name }}!',
        ]);
    }
}

如上例所示,您可以在邮件模板的标题和正文内容中使用 mustache 模板标签!

让我们看一下相应的可邮寄邮件

namespace App\Mail;

use TemplateMailable;

class WelcomeMail extends TemplateMailable
{
    /** @var string */
    public $name;
    
    /** @var string */
    public $email;

    public function __construct(User $user)
    {
        $this->name = $user->name;
        $this->email = $user->email;
    }
}

通过扩展 \Spatie\MailTemplates\TemplateMailable 类,此可邮寄邮件将使用相应的 MailTemplate 渲染。所有 WelcomeMail 上的公共属性都将可在模板中使用。

自定义 MailTemplate 模型

默认的 MailTemplate 模型对于使用 一个 数据库邮件模板为 一个 可邮寄邮件来说已经足够了。如果您想为相同的可邮寄邮件使用多个邮件模板或扩展 MailTemplate 模型,我们强烈建议您发布 mail_template 迁移,并通过扩展 MailTemplate 创建自己的邮件模板模型。请确保还实现了 MailTemplateInterface 接口。

想象一下一个像meetup.com这样的应用程序,它处理不同的聚会小组。该应用程序有几个不同的可邮寄邮件,如NewMeetupPlannedMailMeetupCancelledMail,用于通知用户新的聚会。使用这个包,我们可以为每个聚会小组创建一个MeetupMailTemplate。这样,每个小组都可以在模板中添加自己的内容。MeetupMailTemplate模型可能看起来像这样

use Spatie\MailTemplates\Models\MailTemplate;

class MeetupMailTemplate extends MailTemplate implements MailTemplateInterface
{
    public function meetupGroup(): BelongsTo
    {
        return $this->belongsTo(MeetupGroup::class);
    }
    
    public function scopeForMailable(Builder $query, Mailable $mailable): Builder
    {
        return $query
            ->where('mailable', get_class($mailable))
            ->where('meetup_group_id', $mailable->getMeetupGroupId());
    }
    
    public function getHtmlLayout(): string
    {
        return $this->meetupGroup->mail_layout;
    }
}

MeetupMailTemplate扩展了包的MailTemplate并覆盖了一些方法。我们还添加了与属于此邮件模板的MeetupGroup的关系。

通过扩展getHtmlLayout()方法,我们可以提供组的自定义邮件页眉和页脚。了解更多关于在邮件模板中添加页眉和页脚的信息。

我们还扩展了scopeForMailable()方法,该方法用于从数据库中获取相应的邮件模板。在默认的mailable where子句的基础上,我们添加了一个meetup_group_id where子句,该子句将查询邮件的meeting_group_id

接下来,让我们看看我们的NewMeetupPlannedMail可能是什么样子

use Spatie\MailTemplates\TemplateMailable;

class NewMeetupPlannedMail extends TemplateMailable
{
    // use our custom mail template model
    protected static $templateModelClass = MeetupMailTemplate::class;

    /** @var string */
    public $location;
    
    /** @var \App\Models\Meetup */
    protected $meetup; // protected property, we don't want this in the template data

    public function __construct(Meetup $meetup)
    {
        $this->meetup = $meetup;
        $this->location = $meetup->location;
    }
    
    // provide a method to get the meetup group id so we can use it in MeetupMailTemplate
    public function getMeetupGroupId(): int
    {
        return $this->meetup->meetup_group_id;
    }  
}

发送NewMeetupPlannedMail时,将使用聚会小组正确的MeetupMailTemplate,并使用其自定义内容和邮件布局。非常方便。

模板变量

当为邮件模板构建UI时,您可能希望在自己的wysiwyg编辑器附近显示可用变量的列表。您可以使用getVariables()从可邮寄邮件和邮件模板模型中获取可用变量的列表。

WelcomeMail::getVariables();
// ['name', 'email']

MailTemplate::create(['mailable' => WelcomeMail::class, ... ])->getVariables();
// ['name', 'email']

MailTemplate::create(['mailable' => WelcomeMail::class, ... ])->variables;
// ['name', 'email']

在邮件模板周围添加页眉和页脚

您可以在模板可邮寄邮件或邮件模板上扩展getHtmlLayout()方法。getHtmlLayout()应返回包含{{{ body }}}占位符的字符串布局。

发送TemplateMailable时,编译后的模板将渲染在布局中的{{{ body }}}占位符中,然后再发送。

如果使用Blade视图,占位符需要是@{{{ body }}}

以下示例将使用包装在布局中的模板发送WelcomeMail

use Spatie\MailTemplates\TemplateMailable;

class WelcomeMail extends TemplateMailable
{
    // ...
    
    public function getHtmlLayout(): string
    {
        /**
         * In your application you might want to fetch the layout from an external file or Blade view.
         * 
         * External file: `return file_get_contents(storage_path('mail-layouts/main.html'));`
         * 
         * Blade view: `return view('mailLayouts.main', $data)->render();`
         */
        
        return '<header>Site name!</header>{{{ body }}}<footer>Copyright 2018</footer>';
    }
}

MailTemplate::create([
    'mailable' => WelcomeMail::class,
    'html_template' => '<p>Welcome, {{ name }}!</p>', 
]);

Mail::to($user->email)->send(new WelcomeMail($user));

发送的电子邮件的渲染HTML将如下所示

<header>Site name!</header>
<p>Welcome, John!</p>
<footer>Copyright 2018</footer>

向邮件模板模型添加布局

也可以扩展MailTemplate模型的getHtmlLayout()方法(而不是在可邮寄邮件上扩展getHtmlLayout())。

例如,您可能希望根据邮件模板模型属性使用不同的布局。这可以通过在自定义的MailTemplate模型上添加getHtmlLayout()方法来完成。

以下示例使用基于正在使用的EventMailTemplate的不同布局。如您所见,在这种情况下,布局存储在数据库中的相关Event模型上。

use Spatie\MailTemplates\Models\MailTemplate;

class EventMailTemplate extends MailTemplate
{
    public function event(): BelongsTo
    {
        return $this->belongsTo(Event::class);
    }

    public function getHtmlLayout(): string
    {
        return $this->event->mail_layout_html;
    }
}

翻译邮件模板

默认情况下,此包不支持多语言模板。然而,它与Laravel的本地化可邮寄邮件以及我们的laravel-translatable包完美集成。

只需安装laravel-translatable包,发布create_mail_template_table迁移,将其text列更改为json,并像这样扩展MailTemplate模型

use \Spatie\MailTemplates\MailTemplate;

class MailTemplate extends MailTemplate
{
    use HasTranslations;
    
    public $translatable = ['subject', 'html_template'];
}

测试

composer test

更新日志

有关最近更改的更多信息,请参阅更新日志

贡献

请参阅CONTRIBUTING获取详细信息。

安全

如果您发现了关于安全性的错误,请发送邮件至security@spatie.be,而不是使用问题跟踪器。

鸣谢

许可证

MIT许可证(MIT)。请参阅许可证文件以获取更多信息。