All Projects → spatie → Laravel Database Mail Templates

spatie / Laravel Database Mail Templates

Licence: mit
Render Laravel mailables based on a mail template stored in the database

Projects that are alternatives of or similar to Laravel Database Mail Templates

Laravel Enterprise Starter Kit
👔 Enterprise Web application starter kit or template using Laravel
Stars: ✭ 356 (+57.52%)
Mutual labels:  laravel, template
Laravel Tabler
Laravel Package for integrating Tabler template and this package is Laravel Mix friendly.
Stars: ✭ 20 (-91.15%)
Mutual labels:  laravel, template
Laravel Boilerplate
Laravel Boilerplate / Starter Kit with Gentelella Admin Theme
Stars: ✭ 704 (+211.5%)
Mutual labels:  laravel, template
Workmanger
laravel+vue.js 前后端分离实战项目(项目中wx端等已经存在,因为涉及业务较多,不再更新到github 需要参考可以私聊我)
Stars: ✭ 41 (-81.86%)
Mutual labels:  laravel, template
Laravel template with vue
laravel5.5和vue.js结合的前后端分离项目模板,后端使用了laravel的LTS版本(5.5),前端使用了流行的vue-element-template项目。作为程序的起点,可以直接以此为基础来进行业务扩展。模板内容包括基础的用户管理和权限管理、日志管理、集成第三方登录,整合laravel-echo-server 实现了websocket 做到了消息的实时推送,并在此基础上,实现了聊天室和客服功能。权限管理包括后端Token认证和前端vue.js的动态权限,解决了前后端完整分离的情况下,vue.js的认证与权限相关的痛点,已在本人的多个项目中集成使用。
Stars: ✭ 763 (+237.61%)
Mutual labels:  laravel, template
Phpstorm Laravel Live Templates
Laravel Live Templates for PhpStorm
Stars: ✭ 1,157 (+411.95%)
Mutual labels:  laravel, template
Web
(DEPRECATED) An open source GUI to configure the machinery and to view events that were detected by the machinery.
Stars: ✭ 225 (-0.44%)
Mutual labels:  laravel
Wagonwheel
Offer an online version of your Laravel emails to users.
Stars: ✭ 224 (-0.88%)
Mutual labels:  laravel
Web Socket
Laravel library for asynchronously serving WebSockets.
Stars: ✭ 225 (-0.44%)
Mutual labels:  laravel
Laravel Jwt
Dead simple, plug and play JWT API Authentication for Laravel (5.4+)
Stars: ✭ 225 (-0.44%)
Mutual labels:  laravel
Uniapp Admin
Muti-platform management system for uniapp, H5, Android, IOS, Min Program
Stars: ✭ 226 (+0%)
Mutual labels:  template
Laravel React Blog
基于 Laravel 5.5 和 React 的个人博客系统
Stars: ✭ 226 (+0%)
Mutual labels:  laravel
Play Scala Rest Api Example
Example Play Scala application showing REST API
Stars: ✭ 227 (+0.44%)
Mutual labels:  template
Bootstrap Form
Bootstrap 3 form builder for Laravel
Stars: ✭ 225 (-0.44%)
Mutual labels:  laravel
Laravel Views
Laravel package to create beautiful common views like data tables using the TALL stack.
Stars: ✭ 221 (-2.21%)
Mutual labels:  laravel
Clamav Validator
Laravel virus validator based on ClamAV anti-virus scanner
Stars: ✭ 224 (-0.88%)
Mutual labels:  laravel
Fata
From Apprentice To Artisan. 在线阅读
Stars: ✭ 227 (+0.44%)
Mutual labels:  laravel
Larastan
⚗️ Adds code analysis to Laravel improving developer productivity and code quality.
Stars: ✭ 3,554 (+1472.57%)
Mutual labels:  laravel
Laravel World
provide countries, states, and cities relations and database.
Stars: ✭ 222 (-1.77%)
Mutual labels:  laravel
Laravel Tag Helper
Add powerful HTML tag helpers to your Laravel application
Stars: ✭ 227 (+0.44%)
Mutual labels:  laravel

Render Laravel mailables based on a mail template stored in the database

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

Render Laravel mailables using a template stored in the database.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Quick example

The following example will send a WelcomeMail using a template stored in the database and wrapped in an HTML layout.

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' => WelcomeMail::class,
    'subject' => 'Welcome, {{ name }}',
    'html_template' => '<p>Hello, {{ name }}.</p>',
    'text_template' => 'Hello, {{ name }}.'
]);

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

The HTML for the sent email will look like this:

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

Installation

You can install the package via composer:

composer require spatie/laravel-database-mail-templates

Publish and run the database migrations:

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

If you want to use the default MailTemplate model, all that's left to do is run php artisan migrate to create the mail_templates table.

If you plan on creating a custom MailTemplate model continue by modifying the migration and creating your custom model before running php artisan migrate.

Usage

After installing the package and running the migrations you'll have a new table in your database called mail_templates. This table will be used by the MailTemplate model.

The default MailTemplate has a mailable property that corresponds to the Mailable's class name. It also has a subject and body property which are both used to store mustache template strings.

You might want to set up a seeder that seeds your application's necessary templates:

use Illuminate\Database\Seeder;

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

As you can see in the above example, you can use mustache template tags in both the subject and body of the mail template!

Let's have a look at the corresponding mailable:

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

By extending the \Spatie\MailTemplates\TemplateMailable class this mailable will be rendered using the corresponding MailTemplate. All public properties on the WelcomeMail will be available in the template.

Customizing the MailTemplate model

The default MailTemplate model is sufficient for using one database mail template for one mailable. If you want to use multiple mail templates for the same mailable or extend the MailTemplate model, we highly encourage you to publish the mail_template migration and create your own mail template model by extending MailTemplate. Make sure to implement the MailTemplateInterface interface as well.

Imagine an application like meetup.com that deals with different meetup groups. The application has a couple of different mailables like NewMeetupPlannedMail and MeetupCancelledMail to inform users of new meetups. Using this package we can create a MeetupMailTemplate for each meetup group. This way each group can add their own copy in the template. The MeetupMailTemplate model would look something like this:

use Spatie\MailTemplates\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 extends the package's MailTemplate and overrides a couple of methods. We've also added the relationship to the MeetupGroup that this mail template belongs to.

By extending the getHtmlLayout() method we can provide the group's custom mail header and footer. Read more about adding a header and footer to a mail template.

We've also extended the scopeForMailable() method which is used to fetch the corresponding mail template from the database. On top of the default mailable where-clause we've added a meetup_group_id where-clause that'll query for the mailable's meeting_group_id.

Next, let's have a look at what our NewMeetupPlannedMail might look like:

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

When sending a NewMeetupPlannedMail the right MeetupMailTemplate for the meetup group will be used with its own custom copy and mail layout. Pretty neat.

Template variables

When building a UI for your mail templates you'll probably want to show a list of available variables near your wysiwyg-editor. You can get the list of available variables from both the mailable and the mail template model using the getVariables().

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

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

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

Adding a header and footer around a mail template

You can extend the getHtmlLayout() method on either a template mailable or a mail template. getHtmlLayout() should return a string layout containing the {{{ body }}} placeholder.

When sending a TemplateMailable the compiled template will be rendered inside of the {{{ body }}} placeholder in the layout before being sent.

The following example will send a WelcomeMail using a template wrapped in a layout.

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));

The rendered HTML for the sent email will look like this:

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

Adding a layout to a mail template model

It is also possible to extend the getHtmlLayout() method of the MailTemplate model (instead of extending getHtmlLayout()on the mailable).

You might for example want to use a different layout based on a mail template model property. This can be done by adding the getHtmlLayout() method on your custom MailTemplate model instead.

The following example uses a different layout based on what EventMailTemplate is being used. As you can see, in this case the layout is stored in the database on a related Event model.

use Spatie\MailTemplates\MailTemplate;

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

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

Translating mail templates

Out of the box this package doesn't support multi-langual templates. However, it integrates perfectly with Laravel's localized mailables and our own laravel-translatable package.

Simply install the laravel-translatable package, publish the create_mail_template_table migration, change its text columns to json and extend the MailTemplate model like this:

use \Spatie\MailTemplates\MailTemplate;

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

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].