PHPackages                             spatie/laravel-database-mail-templates - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. spatie/laravel-database-mail-templates

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

spatie/laravel-database-mail-templates
======================================

Render Laravel mailables using a template stored in the database.

3.7.2(2mo ago)446762.6k—5.7%427MITPHPPHP ^7.2|^8.0CI passing

Since Oct 14Pushed 2mo ago7 watchersCompare

[ Source](https://github.com/spatie/laravel-database-mail-templates)[ Packagist](https://packagist.org/packages/spatie/laravel-database-mail-templates)[ Docs](https://github.com/spatie/laravel-database-mail-templates)[ Fund](https://spatie.be/open-source/support-us)[ RSS](/packages/spatie-laravel-database-mail-templates/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (5)Versions (23)Used By (7)

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

[](#render-laravel-mailables-based-on-a-mail-template-stored-in-the-database)

[![Latest Version on Packagist](https://camo.githubusercontent.com/8122617bcbac5d087e4be31ae67716c0281c22404830b47a9143fbcea2538104/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7370617469652f6c61726176656c2d64617461626173652d6d61696c2d74656d706c617465732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/laravel-database-mail-templates)[![Test Status](https://camo.githubusercontent.com/7f20dd8cbdbae6a4af6ba7f6400cb33fb2ca713b68e5532f70a828e6c72fa05d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7370617469652f6c61726176656c2d64617461626173652d6d61696c2d74656d706c617465732f72756e2d74657374732e796d6c3f6c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/7f20dd8cbdbae6a4af6ba7f6400cb33fb2ca713b68e5532f70a828e6c72fa05d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7370617469652f6c61726176656c2d64617461626173652d6d61696c2d74656d706c617465732f72756e2d74657374732e796d6c3f6c6162656c3d7465737473267374796c653d666c61742d737175617265)[![PHP CS Fixer Status](https://camo.githubusercontent.com/115df01653fb941df7d0ff0512f9846f47136db0ed9cc22306f7855f4ba9e7f3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7370617469652f6c61726176656c2d64617461626173652d6d61696c2d74656d706c617465732f7068702d63732d66697865722e796d6c3f6c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/115df01653fb941df7d0ff0512f9846f47136db0ed9cc22306f7855f4ba9e7f3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7370617469652f6c61726176656c2d64617461626173652d6d61696c2d74656d706c617465732f7068702d63732d66697865722e796d6c3f6c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)[![Total Downloads](https://camo.githubusercontent.com/cd6498932ee5efae206e83e51f681d734d8a2c5fd05f37778cd77e99a28368d1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7370617469652f6c61726176656c2d64617461626173652d6d61696c2d74656d706c617465732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/laravel-database-mail-templates)

Render Laravel mailables using a template stored in the database.

Support us
----------

[](#support-us)

[![](https://camo.githubusercontent.com/80b45a960449a1837275622513f30ddb2a2e906e6626fdc6bda7a4bd3ae8467b/68747470733a2f2f6769746875622d6164732e73332e65752d63656e7472616c2d312e616d617a6f6e6177732e636f6d2f6c61726176656c2d64617461626173652d6d61696c2d74656d706c617465732e6a70673f743d31)](https://spatie.be/github-ad-click/laravel-database-mail-templates)

We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).

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](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).

Quick example
-------------

[](#quick-example)

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

```
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' => 'Hello, {{ name }}.',
    'text_template' => 'Hello, {{ name }}.'
]);

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

The HTML for the sent email will look like this:

```
Welcome!
Hello, John.
Copyright 2018
```

Installation
------------

[](#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](#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](#custom-mailtemplate-model) continue by modifying the migration and creating your custom model before running `php artisan migrate`.

Usage
-----

[](#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](http://mustache.github.io/) 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\Mail\WelcomeMail::class,
            'subject' => 'Welcome, {{ name }}',
            'html_template' => 'Hello, {{ name }}!',
            '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:

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

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.

If you need to use properties within your template that are initially defined within your `WelcomeMail` (for example, data that comes from another source). You can call `$this->setAdditionalData()` and pass it an array of you additional key =&gt; value pairs.

An example of this would be:

```
namespace App\Mail;

use TemplateMailable;

class WelcomeMail extends TemplateMailable
{

    public function __construct(User $user)
    {
        $this->setAdditionalData([
            'name' => 'Joe Bloggs'
        ]);
    }
}
```

### Customizing the `MailTemplate` model

[](#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](https://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\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` 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.](#adding-a-header-and-footer-around-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

[](#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

[](#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.

If using a Blade view, the placeholder will need to be `@{{{ body }}}`.

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 'Site name!{{{ body }}}Copyright 2018';
    }
}

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

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

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

```
Site name!
Welcome, John!
Copyright 2018
```

#### Adding a layout to a mail template model

[](#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\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;
    }
}
```

### Translating mail templates

[](#translating-mail-templates)

Out of the box this package doesn't support multi-langual templates. However, it integrates perfectly with [Laravel's localized mailables](https://laravel.com/docs/5.7/mail#localizing-mailables) and our own [laravel-translatable package](https://github.com/spatie/laravel-translatable).

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

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.

### Security

[](#security)

If you've found a bug regarding security please mail  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Alex Vanderbist](https://github.com/alexvanderbist)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

66

—

FairBetter than 99% of packages

Maintenance83

Actively maintained with recent releases

Popularity59

Moderate usage in the ecosystem

Community34

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~134 days

Recently: every ~281 days

Total

21

Last Release

86d ago

Major Versions

0.0.2 → 1.0.02018-10-18

1.0.1 → 2.0.02018-11-19

2.0.0 → 3.0.02019-02-04

PHP version history (3 changes)0.0.1PHP ^7.1

3.1.0PHP ^7.2

3.4.2PHP ^7.2|^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7535935?v=4)[Spatie](/maintainers/spatie)[@spatie](https://github.com/spatie)

---

Top Contributors

[![AlexVanderbist](https://avatars.githubusercontent.com/u/6287961?v=4)](https://github.com/AlexVanderbist "AlexVanderbist (57 commits)")[![freekmurze](https://avatars.githubusercontent.com/u/483853?v=4)](https://github.com/freekmurze "freekmurze (56 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (10 commits)")[![AdrianMrn](https://avatars.githubusercontent.com/u/12762044?v=4)](https://github.com/AdrianMrn "AdrianMrn (9 commits)")[![fulopattila122](https://avatars.githubusercontent.com/u/1162360?v=4)](https://github.com/fulopattila122 "fulopattila122 (6 commits)")[![patinthehat](https://avatars.githubusercontent.com/u/5508707?v=4)](https://github.com/patinthehat "patinthehat (5 commits)")[![yaquawa](https://avatars.githubusercontent.com/u/13927101?v=4)](https://github.com/yaquawa "yaquawa (2 commits)")[![LewBlu](https://avatars.githubusercontent.com/u/36936169?v=4)](https://github.com/LewBlu "LewBlu (2 commits)")[![oguzcandemircan](https://avatars.githubusercontent.com/u/19665071?v=4)](https://github.com/oguzcandemircan "oguzcandemircan (2 commits)")[![ilkermutlu](https://avatars.githubusercontent.com/u/1727029?v=4)](https://github.com/ilkermutlu "ilkermutlu (1 commits)")[![Apfelwurm](https://avatars.githubusercontent.com/u/23552885?v=4)](https://github.com/Apfelwurm "Apfelwurm (1 commits)")[![tof06](https://avatars.githubusercontent.com/u/2961054?v=4)](https://github.com/tof06 "tof06 (1 commits)")[![lloy0076](https://avatars.githubusercontent.com/u/1174532?v=4)](https://github.com/lloy0076 "lloy0076 (1 commits)")[![michaelnabil230](https://avatars.githubusercontent.com/u/46572405?v=4)](https://github.com/michaelnabil230 "michaelnabil230 (1 commits)")[![alexbowers](https://avatars.githubusercontent.com/u/842974?v=4)](https://github.com/alexbowers "alexbowers (1 commits)")[![alexdpunkt](https://avatars.githubusercontent.com/u/3079024?v=4)](https://github.com/alexdpunkt "alexdpunkt (1 commits)")[![simonedelmann](https://avatars.githubusercontent.com/u/2821076?v=4)](https://github.com/simonedelmann "simonedelmann (1 commits)")[![dragonfly4](https://avatars.githubusercontent.com/u/221351?v=4)](https://github.com/dragonfly4 "dragonfly4 (1 commits)")[![CorwinDev](https://avatars.githubusercontent.com/u/88144943?v=4)](https://github.com/CorwinDev "CorwinDev (1 commits)")

---

Tags

customizelaravelmailablephptemplatespatielaravel-database-mail-templates

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/spatie-laravel-database-mail-templates/health.svg)

```
[![Health](https://phpackages.com/badges/spatie-laravel-database-mail-templates/health.svg)](https://phpackages.com/packages/spatie-laravel-database-mail-templates)
```

###  Alternatives

[spatie/laravel-failed-job-monitor

Get notified when a queued job fails

1.0k2.6M4](/packages/spatie-laravel-failed-job-monitor)[spatie/url-signer

Generate a url with an expiration date and signature to prevent unauthorized access

4422.3M16](/packages/spatie-url-signer)[spatie/laravel-url-signer

Laravel implementation of spatie/signed-url

717784.1k3](/packages/spatie-laravel-url-signer)[spatie/mailcoach

Self-host Mailcoach

4007.0k](/packages/spatie-mailcoach)[spatie/mjml-php

Convert MJML to HTML using PHP

272668.4k10](/packages/spatie-mjml-php)[spatie/laravel-slack-slash-command

Make a Laravel app respond to a slash command from Slack

254601.2k2](/packages/spatie-laravel-slack-slash-command)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
