avtonom/email-template-bundle
Installation
Add the bundle to your composer.json:
composer require avtonom/email-template-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Avtonom\EmailTemplateBundle\AvtonomEmailTemplateBundle::class => ['all' => true],
];
Database Migration Run the bundle’s migration to create the required tables:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
The bundle creates:
email_template (stores template content, name, and metadata)email_template_layout (optional layouts for consistent styling)First Template Create a template via the admin interface (if configured) or manually via Doctrine:
$template = new \Avtonom\EmailTemplateBundle\Entity\EmailTemplate();
$template->setName('welcome_email');
$template->setContent('{% extends "base_email.html.twig" %}{% block content %}Hello {{ user.name }}{% endblock %}');
$template->setIsActive(true);
$em->persist($template);
$em->flush();
First Usage Render and send an email in a controller:
use Avtonom\EmailTemplateBundle\Service\EmailTemplateRenderer;
public function sendWelcomeEmail(EmailTemplateRenderer $renderer, $user)
{
$template = $renderer->render('welcome_email', ['user' => $user]);
// Use SwiftMailer to send $template (see Implementation Patterns).
}
Template Management
email_template table with Twig syntax.base_email.html.twig) for consistent headers/footers.trans filter or pass translated variables (e.g., ['greeting' => $this->translator->trans('welcome')]).Rendering Templates
Inject EmailTemplateRenderer service to fetch and render templates:
$html = $renderer->render('template_name', ['var1' => 'value1']);
twig.cache_warmer) for performance.TemplateNotFoundException listener.Integration with SwiftMailer
Combine with Symfony’s Mailer component:
$email = (new Email())
->to($user->getEmail())
->subject('Welcome!')
->html($renderer->render('welcome_email', ['user' => $user]));
$mailer->send($email);
Admin Interface (Optional)
If using the bundle’s admin, configure fos_user or sonata_admin bundles to manage templates via UI.
{# templates/welcome_email.html.twig #}
{% if user.is_premium %}
<p>Enjoy premium features!</p>
{% endif %}
version field to email_template for A/B testing or rollbacks.public/ and reference them in templates:
<img src="{{ asset('images/logo.png') }}" alt="Logo">
Twig Version Mismatch
composer.json:
"twig/twig": "^1.3|^2.0"
Database Schema Changes
src/Resources/config/doctrine/ if needed.Template Not Found
TemplateNotFoundException if the template name doesn’t match the database.is_active = 1) and the name matches exactly (case-sensitive).SwiftMailer HTML Sanitization
SwiftMailer is set to preserve HTML:
# config/packages/swiftmailer.yaml
swiftmailer:
spool: { type: memory }
default_mailer: default
mailers:
default:
transport: %env(MAILER_DSN)%
defaults:
html: true # Critical for HTML emails
config/packages/twig.yaml:
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
file_put_contents(
'debug/email_template.html',
$renderer->render('template_name', $data)
);
$em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
Custom Template Storage
Override the EmailTemplateRepository to fetch templates from an API or S3:
// src/Service/CustomEmailTemplateRepository.php
class CustomEmailTemplateRepository extends \Avtonom\EmailTemplateBundle\Repository\EmailTemplateRepository
{
public function findOneByName($name)
{
// Custom logic (e.g., API call)
}
}
Register as a service:
services:
Avtonom\EmailTemplateBundle\Repository\EmailTemplateRepository:
alias: custom.email_template.repository
Pre-Render Hooks
Extend the EmailTemplateRenderer to add logic before rendering:
$renderer->addPreRenderListener(function ($template, $data) {
$data['current_year'] = date('Y');
return $data;
});
Layout Overrides Replace default layouts by overriding the Twig loader:
twig:
paths:
'%kernel.project_dir%/templates/email': email
Ensure your base_email.html.twig extends from email/base_email.html.twig.
How can I help you explore Laravel packages today?