notebrainslab/filament-email-templates
Installation
composer require notebrainslab/filament-email-templates
Publish the migration and config:
php artisan vendor:publish --provider="Notebrainslab\FilamentEmailTemplates\FilamentEmailTemplatesServiceProvider" --tag="filament-email-templates:migrations"
php artisan vendor:publish --provider="Notebrainslab\FilamentEmailTemplates\FilamentEmailTemplatesServiceProvider" --tag="filament-email-templates:config"
php artisan migrate
Register the Plugin
Add to app/Providers/Filament/AdminPanelProvider.php:
->plugin(Notebrainslab\FilamentEmailTemplates\FilamentEmailTemplatesPlugin::make())
First Use Case Create a template via the Filament UI:
auth.welcome) and merge tags (e.g., {{user.name}})Design Phase
{{order.total}}) for dynamic content.invoices.payment_reminder).Integration with Mailables
Use the HasEmailTemplate trait in your Mailable:
use Notebrainslab\FilamentEmailTemplates\Traits\HasEmailTemplate;
class WelcomeUser extends Mailable
{
use HasEmailTemplate;
public function build()
{
return $this
->subject('Welcome, {{user.name}}!')
->template('auth.welcome')
->with([
'user' => $this->user,
]);
}
}
Dynamic Data Injection
Pass data to templates via the with() method:
->with([
'order' => $order,
'user' => $user,
]);
Access in merge tags: {{order.total}} or {{user.name}}.
Conditional Logic
Use template conditions (e.g., {{#if user.is_premium}}Premium Content{{/if}}) for dynamic blocks.
Template Versioning
Use the version field to track updates without breaking existing mailables.
Reusable Components Create template snippets (e.g., headers/footers) and reuse them across templates.
API-Driven Templates Fetch templates programmatically:
$template = \Notebrainslab\FilamentEmailTemplates\Models\EmailTemplate::where('key', 'auth.welcome')->first();
$html = $template->render(['user' => $user]);
Testing Mock templates in tests:
$this->app->bind(\Notebrainslab\FilamentEmailTemplates\Models\EmailTemplate::class, function () {
return new class extends \Notebrainslab\FilamentEmailTemplates\Models\EmailTemplate {
public function render(array $data) { return 'Mock HTML'; }
};
});
Merge Tag Syntax
{{user.name}} fail if the dot (.) is not escaped or the variable is nested.{{user.name}} (correct) instead of {{user.name}} (if nested objects fail, flatten data in with()).Unlayer Editor Quirks
Caching Headaches
php artisan config:clear
Dark Mode Conflicts
--unlayer-primary) for dynamic theming.Log Rendered Output
Override the render() method in a custom template model:
Log::debug('Template rendered:', ['html' => $html, 'data' => $data]);
Inspect Merge Tags
Use {{debug}} in templates to dump variables:
{{debug user}}
Check Template Existence Verify the key exists in the database:
php artisan tinker
>>> \Notebrainslab\FilamentEmailTemplates\Models\EmailTemplate::where('key', 'auth.welcome')->exists();
Custom Merge Tag Handlers Extend functionality by adding a service provider:
EmailTemplate::extend(function ($template, $data) {
$data['custom_var'] = 'value';
return $data;
});
Template Events Listen for template actions:
Event::listen(\Notebrainslab\FilamentEmailTemplates\Events\TemplateSaved::class, function ($template) {
// Post-save logic
});
Override Unlayer Editor Customize the editor via config:
'unlayer' => [
'options' => [
'toolbar' => ['bold', 'italic', 'custom-button'],
],
],
Localization Translate merge tags dynamically:
->with([
'greeting' => __("Welcome, :name!", ['name' => $user->name]),
]);
Use in template: {{greeting}}.
How can I help you explore Laravel packages today?