devture/symfony-email-template-bundle
Installation
composer require devture/symfony-email-template-bundle
Configure devture/form
Add the required services to config/packages/devture-form.yaml (or equivalent):
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Devture\Component\Form\Token\TemporaryTokenManager:
arguments:
$validityTime: 3600
$secret: "%env(APP_SECRET)%"
$hashFunction: sha256
Devture\Component\Form\Token\TokenManagerInterface:
alias: Devture\Component\Form\Token\TemporaryTokenManager
Devture\Component\Form\Twig\FormExtension:
tags: [twig.extension]
Devture\Component\Form\Twig\TokenExtension:
tags: [twig.extension]
Enable the Bundle
Add to config/bundles.php:
return [
// ...
Devture\EmailTemplateBundle\DevtureEmailTemplateBundle::class => ['all' => true],
];
Configure Storage
Define a Gaufrette filesystem adapter (e.g., config/packages/devture_email_template.yaml):
devture_email_template:
filesystem:
adapter: 'oneup_flysystem_adapter.local'
options:
directory: '%kernel.project_dir%/templates/email'
First Use Case
Create a template via the web UI (/email-template) and send it programmatically:
use Devture\EmailTemplateBundle\Message\EmailTemplateMessage;
$message = (new EmailTemplateMessage())
->setTemplate('welcome')
->setLocale('en')
->setTo('user@example.com')
->setContext(['name' => 'John']);
$mailer->send($message);
Design Templates
Use the web UI (/email-template) to create Twig templates (e.g., welcome.html.twig).
Example template:
<html>
<body>
<h1>Welcome, {{ context.name }}!</h1>
</body>
</html>
Localization
Duplicate templates with language suffixes (e.g., welcome.en.html.twig, welcome.fr.html.twig).
The bundle auto-detects locales.
Context Data
Pass dynamic data via setContext():
$message->setContext([
'name' => 'Alice',
'unsubscribeLink' => url('/unsubscribe'),
]);
// In a service/controller
public function sendWelcomeEmail(User $user)
{
$message = (new EmailTemplateMessage())
->setTemplate('welcome')
->setLocale($user->getLocale())
->setTo($user->getEmail())
->setContext(['name' => $user->getName()]);
$this->mailer->send($message);
}
Use EmailTemplateMessageCollection for bulk sends:
$collection = new EmailTemplateMessageCollection();
foreach ($users as $user) {
$collection->add(
(new EmailTemplateMessage())
->setTemplate('newsletter')
->setTo($user->getEmail())
->setContext(['user' => $user])
);
}
$mailer->send($collection);
Extend the template form via Twig:
{# templates/devture_email_template/form.html.twig #}
{{ form_start(form, {'action': path('devture_email_template_edit', {'id': template.id})}) }}
{{ form_widget(form) }}
<button type="submit">Save</button>
{# Add custom fields here #}
{{ form_row(form.customField) }}
{{ form_end(form) }}
Missing devture/form Setup
Forgetting to configure TemporaryTokenManager or Twig extensions will break the web UI.
Fix: Verify all services in devture/form are properly autowired.
Filesystem Permissions
The bundle stores templates in templates/email/ (default). Ensure the web server user (e.g., www-data) has write access.
Fix: Run chmod -R 775 templates/email or adjust umask in your deployment.
Locale Fallback
If a locale isn’t found, the bundle falls back to en. Override this in config:
devture_email_template:
default_locale: 'en_US'
fallback_locale: 'en'
Caching Headaches Twig templates are cached. Clear the cache after edits:
php bin/console cache:clear
Or disable caching in devture_email_template.yaml:
twig:
cache: false
Template Not Rendering?
Check the filesystem path in config/packages/devture_email_template.yaml and verify the YAML file exists (e.g., templates/email/welcome.en.yaml).
Debug: Enable debug mode and inspect the rendered template:
$message = new EmailTemplateMessage();
$message->setTemplate('welcome')->setLocale('en');
dump($message->getRenderedTemplate());
404 on Web UI
Ensure the route is registered (check config/routes/devture_email_template.yaml):
devture_email_template:
resource: "@DevtureEmailTemplateBundle/Resources/config/routing.yaml"
Custom Template Directories Override the filesystem adapter to use a remote storage (e.g., S3):
devture_email_template:
filesystem:
adapter: 'oneup_flysystem_adapter.aws_s3'
options:
bucket: 'my-email-templates'
region: 'us-east-1'
Pre/Post-Send Hooks Subscribe to events in a subscriber:
use Devture\EmailTemplateBundle\Event\EmailTemplateEvents;
public static function getSubscribedEvents()
{
return [
EmailTemplateEvents::PRE_SEND => 'onPreSend',
];
}
public function onPreSend(EmailTemplateEvent $event)
{
$event->getMessage()->getHeaders()->addTextHeader('X-Custom', 'value');
}
Validation Rules Extend the template form type to add custom validation:
use Devture\EmailTemplateBundle\Form\Type\EmailTemplateType;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('customField', TextType::class, [
'constraints' => [new Length(['max' => 255])],
]);
}
devture_email_template.twig.debug: false to avoid recompiling templates on every request.symfony/mailer async transport for high-volume sends:
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
transports:
async: '%env(MAILER_ASYNC_DSN)%'
How can I help you explore Laravel packages today?