visualbuilder/email-templates

Filament 的电子邮件模板编辑器


README

Latest Version on Packagist Total Downloads run-tests

为什么企业和应用程序应该使用电子邮件模板

  • 节省时间:电子邮件模板消除了从头创建电子邮件的需要,节省了宝贵的时间和精力。
  • 可定制性:快速编辑功能使员工能够在保持专业外观的同时个性化模板内容。
  • 一致性品牌:模板确保所有电子邮件都符合品牌指南,加强品牌识别度和专业性。
  • 专业外观:精心设计的模板提供整洁一致的外观,增强企业的信誉和声誉。
  • 简化沟通:及时高效的沟通。
  • 灵活性:模板可以适应各种用途,如促销电子邮件、客户支持响应、通讯稿等。
  • 易于更新:模板可以轻松修改,以反映报价、政策或设计元素的更改,确保沟通保持最新并与业务目标一致。
  • 标准化:模板强制执行电子邮件的标准结构和格式,减少错误并提高沟通的清晰度。
  • 可扩展性:电子邮件模板便于在业务增长时保持一致的信息传递,确保所有互动中的客户体验保持一致。
  • 提高生产力:通过快速访问模板,员工可以更多地关注核心任务,从而提高企业整体的生产力。

此包提供:

  • 电子邮件模板的内容管理,允许授权用户在管理界面中编辑电子邮件模板内容。
  • 模板可以包括模型属性令牌或配置值,这些将被替换,例如##user.name##或##config.app.name##
  • 模板可以保存不同的地区设置以实现多语言功能。
  • 一个通用的方法,用于快速创建邮件类,以加快添加新模板和自动化可能性。
  • 主题编辑器 - 设置您自己的颜色并将其应用于特定模板。

我们使用标准的 Laravel 邮件发送功能,该包仅允许内容编辑和快速添加新的模板类。

Email Preview

安装

通过 composer 获取此包

composer require visualbuilder/email-templates

运行安装命令会将模板视图、迁移、种子器和配置文件复制到您的应用程序中。

使用 --seed 选项将填充 7 个默认模板,您可以在管理面板中编辑这些模板。

 php artisan filament-email-templates:install --seed

注意:如果您希望预先填充自己的内容,也可以直接编辑种子器。 database\Seeders\EmailTemplateSeeder.php

将插件添加到面板

使用 app/Providers/Filament/AdminPanelProvider.php 中的 plugins() 方法将此插件添加到面板

use Visualbuilder\EmailTemplates\EmailTemplatesPlugin;
 
public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugins([
            EmailTemplatesPlugin::make(),
            // ...
        ]);
}

可以在配置中设置菜单组和排序顺序

用法

HTML 编辑器

在管理界面中编辑电子邮件内容,并使用令牌注入模型或配置内容。 Email Preview

令牌

令牌格式为##model.attribute##。在调用电子邮件时,将任何引用的模型传递以自动替换令牌。

您还可以包含配置值,格式为##config.file.key##,例如##config.app.name##。

在电子邮件模板配置文件中,您必须指定允许替换的键。

    /**
     * Allowed config keys which can be inserted into email templates
     * eg use ##config.app.name## in the email template for automatic replacement.
     */
    'config_keys' => [
        'app.name',
        'app.url',
        'email-templates.customer-services'

实施即用型模板

电子邮件可以直接发送,也可以通过通知或事件监听器发送。

以下电子邮件模板包括以帮助您开始,并展示不同的发送方法。

  • 用户注册 - 欢迎他们加入平台
  • 用户验证邮箱 - 确认他们是人类
  • 用户已验证邮箱 - 是的,他们确实是
  • 用户请求重置密码 - 让他们更改密码
  • 用户密码重置成功 - 哇,你已经更改了密码
  • 用户被锁定 - 哎呀 - 现在怎么办?
  • 用户登录 - 成功

并非所有系统都需要登录通知,但出于安全考虑,这里仍然包括。

新用户注册邮件

在创建新用户时,会触发一个新的注册事件。

我们想通过友好的邮件欢迎新用户,因此我们包括了一个监听器来监听 Illuminate\Auth\Events\Registered 事件,如果配置中已启用,它将发送邮件:

  'send_emails'             => [
        'new_user_registered'    => true,
        'verification'           => true,
        'user_verified'          => true,
        'login'                  => true,
        'password_reset_success' => true,
    ],

用户验证邮箱

这个通知是内置在 Laravel 中的,所以我们覆盖了默认的 toMail 函数,以使用我们的自定义邮件模板。

这可以在 EmailTemplatesAuthServiceProvider 中完成。

这可以在配置中禁用。

要启用邮箱验证,确保用户模型实现了 Laravel MustVerifyEmail 合约:

class User extends Authenticatable implements MustVerifyEmail

并在你的路由中包含 verified 中间件。

用户请求重置密码

这是 Laravel 内置的另一个通知,但要启用自定义邮件,只需将此函数添加到你的可认证用户模型中。

use Visualbuilder\EmailTemplates\Notifications\UserResetPasswordRequestNotification;

/**
     * @param $token
     *
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $url = \Illuminate\Support\Facades\URL::secure(route('password.reset', ['token' => $token, 'email' =>$this->email]));

        $this->notify(new UserResetPasswordRequestNotification($url));
    }

自定义邮件模板

提供了一些主题颜色选项。除非你在邮件模板中指定,否则邮件模板将使用默认主题。

在配置文件 config/filament-email-templates.php 中可以设置标志、联系人和管理员偏好设置

    //Default Logo
    'logo'                    => 'media/email-templates/logo.png',

    //Logo size in pixels -> 200 pixels high is plenty big enough.
    'logo_width'              => '476',
    'logo_height'             => '117',

    //Content Width in Pixels
    'content_width'           => '600',

    //Contact details included in default email templates
    'customer-services'  => ['email' => 'support@yourcompany.com',
                             'phone' => '+441273 455702'],

    //Footer Links
    'links'                   => [
        ['name' => 'Website', 'url' => 'https://yourwebsite.com', 'title' => 'Goto website'],
        ['name' => 'Privacy Policy', 'url' => 'https://yourwebsite.com/privacy-policy', 'title' => 'View Privacy Policy'],
    ],

如果你希望直接编辑模板 blade 文件,请在此查看主要模板

  • 路径: resources/views/vendor/vb-email-templates/email/default.php

此目录中的新模板将自动在邮件模板编辑器的下拉菜单中可见以供选择。

有用提示

并非所有邮件客户端(例如 Outlook)都能有效地渲染样式表中的 CSS。为了确保最大的兼容性,最好将样式放入行内。为了检查你的邮件在不同客户端中的外观,强烈推荐使用 Litmus Email Previews

翻译

每个邮件模板都有一个键和一种语言

  • : user-password-reset
  • 语言: en_gb

这允许根据用户的地区选择相关的模板 - 你需要保存用户的首选语言来实现这一点。

请注意,Laravel 默认地区是“en”,我们更喜欢将英国英语和美国英语分开,通常使用 en_GB 和 en_US,但你可以根据需要设置此值。

可以在配置中设置要在语言选择器中显示的语言

    'default_locale'   => 'en_GB',

    //These will be included in the language picker when editing an email template
    'languages'        => [
        'en_GB' => ['display' => 'British', 'flag-icon' => 'gb'],
        'en_US' => ['display' => 'USA', 'flag-icon' => 'us'],
        'es'    => ['display' => 'Español', 'flag-icon' => 'es'],
        'fr'    => ['display' => 'Français', 'flag-icon' => 'fr'],
        'in'    => ['display' => 'Hindi', 'flag-icon' => 'in'],
        'pt'    => ['display' => 'Brasileiro', 'flag-icon' => 'br'],
    ]

Language Picker

标志图标从 CDN 加载:https://cdn.jsdelivr.net.cn/gh/lipis/flag-icons@6.6.6/css/flag-icons.min.css 查看 https://npmjs.net.cn/package/flag-icons

创建新的邮件类

我们目前选择为每种电子邮件类型使用单独的 Mailable 类。这意味着当你创建一个新模板时,它将需要一个新 PHP 类。该包提供了一个操作,如果 app\Mail\VisualBuilder\EmailTemplates 中不存在文件,则构建类。

Build Class 目前生成的 Mailable 类将使用 BuildGenericEmail 特性

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Visualbuilder\EmailTemplates\Traits\BuildGenericEmail;

class MyFunkyNewEmail extends Mailable
{
    use Queueable, SerializesModels, BuildGenericEmail;

    public string $template = 'email-template-key';  //Change this to the key of the email template content to load
    public string $sendTo;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($user) {
        $this->sendTo = $user;
    }
}

在电子邮件中包含其他模型进行令牌替换

只需传递你需要传递的模型,并在构造函数中分配它们。

class MyFunkyNewEmail extends Mailable
{
    use Queueable, SerializesModels, BuildGenericEmail;

    public string $template = 'email-template-key';  //Change this to the key of the email template content to load
    public string $sendTo;
    public Model $booking;

    public function __construct($user, Booking $booking) {
            $this->user       = $user;
            $this->booking    = $booking;
            $this->sendTo     = $user->email;
        }

在这个例子中,你可以使用 ##booking.date## 或 booking 模型中可用的任何属性。

如果你需要派生某些属性,你可以在你的模型中添加访问器。

这两个函数都可以让您使用:

##user.full_name## 在电子邮件模板中:

public function getFullNameAttribute()
{
  return $this->firstname.' '.$this->lastname;
}

或者

protected function fullName(): Attribute
{
    return Attribute::make(
        get: fn () => $this->firstname.' '.$this->lastname,
    );
}

添加附件

在这里,您可以看到如何传递一个附件:

附件应该传递给邮件类,并设置为公共属性。

在这种情况下,我们传递了一个订单模型和一个包含PDF的发票模型。

class SalesOrderEmail extends Mailable
{
    use Queueable, SerializesModels, BuildGenericEmail;

    public string $template = 'email-template-key';
    public string $sendTo;
    public $attachment;
    public User $user;
    public Order $order;
    public Invoice $invoice;

    /**
     * Constructor for SalesOrderEmail.
     *
     * @param User $user User object
     * @param Order $order Order object
     * @param Invoice $invoice Invoice object
     */
    public function __construct($user, $order, $invoice) {
        $this->user = $user;
        $this->order = $order;
        $this->invoice = $invoice;
        $this->attachment = $invoice->getPdf(); // Missing semicolon added
        $this->sendTo = $user->email;
    }
}

*** 更新 *** 从php8.0开始,上述代码可以缩短为:

class SalesOrderEmail extends Mailable
{
    use Queueable, SerializesModels, BuildGenericEmail;

    public string $template = 'email-template-key'; 
    public string $sendTo;
    public $attachment;

    /**
     * Constructor for SalesOrderEmail using PHP 8 constructor property promotion.
     *
     * @param User $user User object
     * @param Order $order Order object
     * @param Invoice $invoice Invoice object
     */
    public function __construct(public User $user, public Order $order, public Invoice $invoice) {
        $this->attachment = $invoice->getPdf(); 
        $this->sendTo = $user->email;
    }
}

附件在BuildGenericEmail特性的build函数中处理。您可以使用attachment->filename自定义文件名。您还应该包括文件类型。

 public function build() {
        $template = EmailTemplate::findEmailByKey($this->template, App::currentLocale());

        if($this->attachment ?? false) {
            $this->attach(
                $this->attachment->filepath, [
                'as'   => $this->attachment->filename,
                'mime' => $this->attachment->filetype
            ]
            );
        }

        $data = [
            'content'       => TokenHelper::replace($template->content, $this),
            'preHeaderText' => TokenHelper::replace($template->preheader, $this),
            'title'         => TokenHelper::replace($template->title, $this)
        ];

        return $this->from($template->from['email'],$template->from['name'])
            ->view($template->view_path)
            ->subject(TokenHelper::replace($template->subject, $this))
            ->to($this->sendTo)
            ->with(['data'=>$data]);
    }

为了最大程度地提高兼容性,我们仍然使用L9的mailable方法 ->,这仍然在L10上工作。

测试

./vendor/bin/pest      

变更日志

请参阅变更日志以获取有关最近更改的更多信息。

贡献

请参阅贡献指南以获取详细信息。

安全

如果您发现任何与安全相关的问题,请通过电子邮件发送至support@ekouk.com,而不是使用问题跟踪器。

鸣谢

许可

GNU GPLv3。请参阅许可文件以获取更多信息。