I render emails using Twig.
To import CSS directly into the email, I did the following:
<style>
{{ source('@public/build/email.css') }}
</style>
This works well in dev environment, but does not in production, where assets are versioned (e.g. email.dfase343.css).
Is it possible to only disable versioning for this single file?
My webpack.config.js ist pretty basic:
var Encore = require('@symfony/webpack-encore');
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.addEntry('app', './assets/js/app.js')
.addEntry('email', './assets/js/email.js')
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction()) // --> only for app.js
.enableSassLoader()
;
module.exports = Encore.getWebpackConfig();
I wrote a simple Twig function to get around this issue:
<?php
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class AppExtension extends AbstractExtension
{
private $assetsManager;
public function __construct(\Symfony\Component\Asset\Packages $assetsManager)
{
$this->assetsManager = $assetsManager;
}
public function getFunctions()
{
return array(
new TwigFunction('asset_embed', array($this, 'assetEmbed')),
);
}
public function assetEmbed($uri, $package = null)
{
$file = __DIR__.'/../../public'.$this->assetsManager->getUrl($uri, $package);
if (is_file($file)) {
return file_get_contents($file);
}
throw new \Twig_Error('File "'.$file.'" not found.');
}
}
<style>
{{ asset_embed('build/email.css') }}
</style>
While this doesn't answer the question in your title, it will let you get the CSS from the webpack generated file(s) to include in your email.
Webpack Encore creates a file in your build folder called "entrypoints.js". You'll want to get and parse that file using $decodedFile = json_decode(file_get_contents('your/build/folder/entrypoints.json'));.
You can then traverse the contents of that file as an object. The file path you want will be at something like $decodedFile->entrypoints->email->css, which will give you an array of the CSS files for that entry (there can be more than one file, for example if you have the .splitEntryChunks() method in your webpack.config.js file.
After you've got that, you'll want to do file_get_contents($yourCssFile) for each file in that array to get the CSS from each file. Bear in mind though that the paths in that file are the web-accessible paths, not the local paths, so you might need to manipulate them.
Of course you can only do all that in PHP, so you'll need to create a Twig extension to allow you to use it in your template.
I'm surprised there isn't a better way to do that in Symfony - I'd love to know of one if there is.
Full code (To be used in a Twig extension method https://symfony.com/doc/current/templating/twig_extension.html, or just pass $css into your template):
$files = json_decode(file_get_contents('your/build/folder/entrypoints.json'))
->entrypoints
->email
->css
;
$css = '';
foreach ($files as $file) {
$css .= file_get_contents('your/build/folder/') . basename($file));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With