Installation:
composer require notfloran/mjml-bundle
For Symfony Flex projects, this auto-registers the bundle. For non-Flex projects, manually add new NotFloran\MjmlBundle\MjmlBundle() to AppKernel.php.
First Use Case: Render an MJML template via the binary renderer:
use NotFloran\MjmlBundle\Renderer\BinaryRenderer;
$renderer = new BinaryRenderer();
$html = $renderer->render('<mjml><mj-body><mj-section><mj-column><mj-text>Hello World!</mj-text></mj-column></mj-section></mj-body></mjml>');
Where to Look First:
config/packages/notfloran_mjml.yaml for default settings (e.g., MJML binary path, version).BinaryRenderer for direct usage or extend it for custom logic.MjmlExtension for seamless template rendering.Direct Rendering:
Use the BinaryRenderer for one-off MJML-to-HTML conversions:
$renderer = $container->get('notfloran_mjml.renderer.binary');
$html = $renderer->render($mjmlString);
Twig Integration: Extend Twig templates with MJML syntax:
{% mjml %}
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>{{ message }}</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
{% endmjml %}
Render via:
$html = $twig->render('path/to/template.twig');
Service Integration: Inject the renderer into services for reusable logic:
class EmailService {
public function __construct(private BinaryRenderer $renderer) {}
public function generateEmailTemplate(string $content): string {
return $this->renderer->render($content);
}
}
Configuration Overrides:
Customize MJML binary path or version in config/packages/notfloran_mjml.yaml:
notfloran_mjml:
binary_path: '/custom/path/to/mjml'
version: '4.14.1'
$email = (new Email())
->html($renderer->render($mjmlTemplate))
->subject('Your MJML Email');
$mailer->send($email);
BinaryRenderer in tests to avoid dependency on the MJML binary:
$this->mockBuilder()
->disableOriginalConstructor()
->getMock()
->method('render')
->willReturn('<html>Mocked HTML</html>');
Binary Dependencies:
Twig Caching:
{% mjml autoescape=false %} to avoid double-escaping issues.Configuration Overrides:
notfloran_mjml.yaml require a cache clear:
php bin/console cache:clear
Version Mismatches:
composer.json and config align (e.g., version: '4' in config for MJML 4).Dockerfile:
RUN npm install -g mjml@4
Custom Renderers:
Extend BinaryRenderer to add pre/post-processing:
class CustomRenderer extends BinaryRenderer {
public function render(string $mjml): string {
$html = parent::render($mjml);
return $this->postProcess($html);
}
}
Register as a service:
services:
NotFloran\MjmlBundle\Renderer\CustomRenderer: ~
Twig Filters: Add MJML-specific Twig filters (e.g., for dynamic MJML generation):
$twig->addFilter(new \Twig\TwigFilter('mjml_component', [$renderer, 'renderComponent']));
Event Listeners: Hook into MJML rendering events (e.g., to modify templates before conversion):
$eventDispatcher->addListener(
'notfloran_mjml.render',
[$this, 'onMjmlRender']
);
How can I help you explore Laravel packages today?