{"id":19324854,"url":"https://github.com/spatie/laravel-database-mail-templates","last_synced_at":"2025-05-14T11:08:54.437Z","repository":{"id":46747379,"uuid":"152581258","full_name":"spatie/laravel-database-mail-templates","owner":"spatie","description":"Render Laravel mailables based on a mail template stored in the database","archived":false,"fork":false,"pushed_at":"2025-02-21T13:09:14.000Z","size":124,"stargazers_count":429,"open_issues_count":2,"forks_count":43,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-14T03:57:59.272Z","etag":null,"topics":["customize","laravel","mailable","php","template"],"latest_commit_sha":null,"homepage":"https://spatie.be/open-source","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spatie.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"https://spatie.be/open-source/support-us"}},"created_at":"2018-10-11T11:32:51.000Z","updated_at":"2025-04-04T04:40:50.000Z","dependencies_parsed_at":"2024-06-04T12:38:03.851Z","dependency_job_id":"e4000a8a-ca8d-4c4b-8ede-a2cdc8d69577","html_url":"https://github.com/spatie/laravel-database-mail-templates","commit_stats":{"total_commits":114,"total_committers":23,"mean_commits":4.956521739130435,"dds":0.5614035087719298,"last_synced_commit":"174fdc62c4dcee65fbc3b2a9e701d0c92c4b0c7f"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Flaravel-database-mail-templates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Flaravel-database-mail-templates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Flaravel-database-mail-templates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Flaravel-database-mail-templates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spatie","download_url":"https://codeload.github.com/spatie/laravel-database-mail-templates/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254129484,"owners_count":22019628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["customize","laravel","mailable","php","template"],"created_at":"2024-11-10T02:07:08.592Z","updated_at":"2025-05-14T11:08:54.401Z","avatar_url":"https://github.com/spatie.png","language":"PHP","funding_links":["https://spatie.be/open-source/support-us"],"categories":[],"sub_categories":[],"readme":"# Render Laravel mailables based on a mail template stored in the database\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-database-mail-templates.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-database-mail-templates)\n![Test Status](https://img.shields.io/github/actions/workflow/status/spatie/laravel-database-mail-templates/run-tests.yml?label=tests\u0026style=flat-square)\n![PHP CS Fixer Status](https://img.shields.io/github/actions/workflow/status/spatie/laravel-database-mail-templates/php-cs-fixer.yml?label=code%20style\u0026style=flat-square)\n[![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-database-mail-templates.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-database-mail-templates)\n\nRender Laravel mailables using a template stored in the database.\n\n## Support us\n\n[\u003cimg src=\"https://github-ads.s3.eu-central-1.amazonaws.com/laravel-database-mail-templates.jpg?t=1\" width=\"419px\" /\u003e](https://spatie.be/github-ad-click/laravel-database-mail-templates)\n\nWe 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).\n\nWe 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).\n\n## Quick example\n\nThe following example will send a `WelcomeMail` using a template stored in the database and wrapped in an HTML layout.\n\n```php\nnamespace App\\Mail;\n\nuse Spatie\\MailTemplates\\TemplateMailable;\n\nclass WelcomeMail extends TemplateMailable\n{\n    /** @var string */\n    public $name;\n\n    public function __construct(User $user)\n    {\n        $this-\u003ename = $user-\u003ename;\n    }\n    \n    public function getHtmlLayout(): string\n    {\n        $pathToLayout = storage_path('mail-layouts/main.html');\n    \n        return file_get_contents($pathToLayout);\n    }\n}\n\nMailTemplate::create([\n    'mailable' =\u003e \\App\\Mail\\WelcomeMail::class,\n    'subject' =\u003e 'Welcome, {{ name }}',\n    'html_template' =\u003e '\u003cp\u003eHello, {{ name }}.\u003c/p\u003e',\n    'text_template' =\u003e 'Hello, {{ name }}.'\n]);\n\nMail::to($user-\u003eemail)-\u003esend(new WelcomeMail($user));\n```\n\nThe HTML for the sent email will look like this:\n\n```html\n\u003cheader\u003eWelcome!\u003c/header\u003e\n\u003cp\u003eHello, John.\u003c/p\u003e\n\u003cfooter\u003eCopyright 2018\u003c/footer\u003e\n```\n\n## Installation\n\nYou can install the package via composer:\n\n```bash\ncomposer require spatie/laravel-database-mail-templates\n```\n\nPublish and run the database migrations:\n\n```bash\nphp artisan vendor:publish --provider=\"Spatie\\MailTemplates\\MailTemplatesServiceProvider\" --tag=\"migrations\"\n```\n\nIf 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. \n\nIf 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`.\n\n## Usage\n\nAfter 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.\n\nThe 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.\n\nYou might want to set up a seeder that seeds your application's necessary templates:\n\n```php\nuse Illuminate\\Database\\Seeder;\n\nclass MailTemplatesSeeder extends Seeder\n{\n    public function run()\n    {\n        MailTemplate::create([\n            'mailable' =\u003e \\App\\Mail\\WelcomeMail::class,\n            'subject' =\u003e 'Welcome, {{ name }}',\n            'html_template' =\u003e '\u003ch1\u003eHello, {{ name }}!\u003c/h1\u003e',\n            'text_template' =\u003e 'Hello, {{ name }}!',\n        ]);\n    }\n}\n```\n\nAs you can see in the above example, you can use mustache template tags in both the subject and body of the mail template!\n\nLet's have a look at the corresponding mailable:\n\n```php\nnamespace App\\Mail;\n\nuse TemplateMailable;\n\nclass WelcomeMail extends TemplateMailable\n{\n    /** @var string */\n    public $name;\n    \n    /** @var string */\n    public $email;\n\n    public function __construct(User $user)\n    {\n        $this-\u003ename = $user-\u003ename;\n        $this-\u003eemail = $user-\u003eemail;\n    }\n}\n```\n\nBy 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.\n\nIf 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-\u003esetAdditionalData()` and pass it an array of you additional key =\u003e value pairs.\n\nAn example of this would be:\n```php\nnamespace App\\Mail;\n\nuse TemplateMailable;\n\nclass WelcomeMail extends TemplateMailable\n{\n\n    public function __construct(User $user)\n    {\n        $this-\u003esetAdditionalData([\n            'name' =\u003e 'Joe Bloggs'\n        ]);\n    }\n}\n```\n\n### Customizing the `MailTemplate` model\n\nThe 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.\n\nImagine 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.\nUsing 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:\n\n```php\nuse Spatie\\MailTemplates\\Models\\MailTemplate;\n\nclass MeetupMailTemplate extends MailTemplate implements MailTemplateInterface\n{\n    public function meetupGroup(): BelongsTo\n    {\n        return $this-\u003ebelongsTo(MeetupGroup::class);\n    }\n    \n    public function scopeForMailable(Builder $query, Mailable $mailable): Builder\n    {\n        return $query\n            -\u003ewhere('mailable', get_class($mailable))\n            -\u003ewhere('meetup_group_id', $mailable-\u003egetMeetupGroupId());\n    }\n    \n    public function getHtmlLayout(): string\n    {\n        return $this-\u003emeetupGroup-\u003email_layout;\n    }\n}\n``` \n\n`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.\n\nBy 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) \n\nWe've also extended the `scopeForMailable()` method which is used to fetch the corresponding mail template from the database. \nOn 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`.\n\nNext, let's have a look at what our `NewMeetupPlannedMail` might look like:\n\n```php\nuse Spatie\\MailTemplates\\TemplateMailable;\n\nclass NewMeetupPlannedMail extends TemplateMailable\n{\n    // use our custom mail template model\n    protected static $templateModelClass = MeetupMailTemplate::class;\n\n    /** @var string */\n    public $location;\n    \n    /** @var \\App\\Models\\Meetup */\n    protected $meetup; // protected property, we don't want this in the template data\n\n    public function __construct(Meetup $meetup)\n    {\n        $this-\u003emeetup = $meetup;\n        $this-\u003elocation = $meetup-\u003elocation;\n    }\n    \n    // provide a method to get the meetup group id so we can use it in MeetupMailTemplate\n    public function getMeetupGroupId(): int\n    {\n        return $this-\u003emeetup-\u003emeetup_group_id;\n    }  \n}\n```\nWhen sending a `NewMeetupPlannedMail` the right `MeetupMailTemplate` for the meetup group will be used with its own custom copy and mail layout. Pretty neat.\n\n### Template variables\n\nWhen building a UI for your mail templates you'll probably want to show a list of available variables near your wysiwyg-editor.\nYou can get the list of available variables from both the mailable and the mail template model using the `getVariables()`.\n\n```php\nWelcomeMail::getVariables();\n// ['name', 'email']\n\nMailTemplate::create(['mailable' =\u003e WelcomeMail::class, ... ])-\u003egetVariables();\n// ['name', 'email']\n\nMailTemplate::create(['mailable' =\u003e WelcomeMail::class, ... ])-\u003evariables;\n// ['name', 'email']\n```\n\n### Adding a header and footer around a mail template\n\nYou can extend the `getHtmlLayout()` method on either a template mailable or a mail template. `getHtmlLayout()` should return a string layout containing the `{{{ body }}}` placeholder. \n\nWhen sending a `TemplateMailable` the compiled template will be rendered inside of the `{{{ body }}}` placeholder in the layout before being sent.\n\nIf using a Blade view, the placeholder will need to be `@{{{ body }}}`.\n\nThe following example will send a `WelcomeMail` using a template wrapped in a layout.\n\n```php\nuse Spatie\\MailTemplates\\TemplateMailable;\n\nclass WelcomeMail extends TemplateMailable\n{\n    // ...\n    \n    public function getHtmlLayout(): string\n    {\n        /**\n         * In your application you might want to fetch the layout from an external file or Blade view.\n         * \n         * External file: `return file_get_contents(storage_path('mail-layouts/main.html'));`\n         * \n         * Blade view: `return view('mailLayouts.main', $data)-\u003erender();`\n         */\n        \n        return '\u003cheader\u003eSite name!\u003c/header\u003e{{{ body }}}\u003cfooter\u003eCopyright 2018\u003c/footer\u003e';\n    }\n}\n\nMailTemplate::create([\n    'mailable' =\u003e WelcomeMail::class,\n    'html_template' =\u003e '\u003cp\u003eWelcome, {{ name }}!\u003c/p\u003e', \n]);\n\nMail::to($user-\u003eemail)-\u003esend(new WelcomeMail($user));\n```\n\nThe rendered HTML for the sent email will look like this:\n\n```html\n\u003cheader\u003eSite name!\u003c/header\u003e\n\u003cp\u003eWelcome, John!\u003c/p\u003e\n\u003cfooter\u003eCopyright 2018\u003c/footer\u003e\n```\n\n#### Adding a layout to a mail template model\n\nIt is also possible to extend the `getHtmlLayout()` method of the `MailTemplate` model (instead of extending `getHtmlLayout()`on the mailable).\n\nYou 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. \n\nThe 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.\n\n```php\nuse Spatie\\MailTemplates\\Models\\MailTemplate;\n\nclass EventMailTemplate extends MailTemplate\n{\n    public function event(): BelongsTo\n    {\n        return $this-\u003ebelongsTo(Event::class);\n    }\n\n    public function getHtmlLayout(): string\n    {\n        return $this-\u003eevent-\u003email_layout_html;\n    }\n}\n``` \n\n### Translating mail templates\n\nOut 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).\n\nSimply 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:\n\n```php\nuse \\Spatie\\MailTemplates\\MailTemplate;\n\nclass MailTemplate extends MailTemplate\n{\n    use HasTranslations;\n    \n    public $translatable = ['subject', 'html_template'];\n}\n```\n\n### Testing\n\n``` bash\ncomposer test\n```\n\n### Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.\n\n### Security\n\nIf you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker.\n\n## Credits\n\n- [Alex Vanderbist](https://github.com/alexvanderbist)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspatie%2Flaravel-database-mail-templates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspatie%2Flaravel-database-mail-templates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspatie%2Flaravel-database-mail-templates/lists"}