Я визуализирую электронные письма с помощью Twig.
Чтобы импортировать CSS прямо в письмо, я сделал следующее:
<style>
{{ source('@public/build/email.css') }}
</style>
Это хорошо работает в среде разработки, но не работает в производственной среде, где для ресурсов используются версии (например, email.dfase343.css).
Можно ли отключить управление версиями только для этого файла?
Мой webpack.config.js довольно прост:
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();
Я написал простую функцию Twig, чтобы обойти эту проблему:
<?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>
На самом деле я не уверен, как именно работает webpack, но я следовал руководствам Symfony. В моем файле email.js есть это: import '../css/email.scss';
На самом деле я не понимаю вашей проблемы, почему управление версиями влияет на ваш шаблон электронной почты?
{{ source('@public/build/email.css') }} - это функция Twig, которая загружает содержимое файла в текущий шаблон. Поскольку я хочу использовать SCSS в своем шаблоне электронной почты, мне нужно настроить процесс сборки. source, кроме asset, не использует файл manifest.json для преобразования чистого пути в версионный путь. Так думает Твиг, файл можно найти по адресу build/email.css, тогда как на самом деле он находится по адресу build/email.sdf312321.css.
Я думаю, вам нужно использовать asset () вместо source () {{asset ('build / email.css')}} symfony.com/doc/current/frontend/encore/…
Конечно, но вы не можете сделать это с электронной почтой. Для правильной работы электронной почты требуется встроенный CSS. Я уже думал о создании настраиваемой функции, такой как asset_embed, но я надеялся, что смогу добиться этого из коробки, не создавая некоторых настраиваемых основных функций.




Не уверен, что это хорошее решение, но вы можете попробовать добавить плагин ignore-loader и сопоставить файлы, чтобы игнорировать их, например в webpack.config.js игнорировать все файлы .css
module.exports = {
// ... other configurations ...
module: {
loaders: [
{ test: /\.css$/, loader: 'ignore-loader' }
]
}
};
Хотя это не отвечает на вопрос в вашем заголовке, это позволит вам получить CSS из файла (ов), сгенерированного веб-пакетом, для включения в вашу электронную почту.
Webpack Encore создает в папке сборки файл с именем «entrypoints.js». Вы захотите получить и проанализировать этот файл с помощью $decodedFile = json_decode(file_get_contents('your/build/folder/entrypoints.json'));.
Затем вы можете просматривать содержимое этого файла как объекта. Путь к файлу, который вы хотите, будет примерно таким, как $decodedFile->entrypoints->email->css, что даст вам массив файлов CSS для этой записи (может быть несколько файлов, например, если у вас есть метод .splitEntryChunks() в вашем файле webpack.config.js .
После этого вы захотите выполнить file_get_contents($yourCssFile) для каждого файла в этом массиве, чтобы получить CSS из каждого файла. Однако имейте в виду, что пути в этом файле - это пути, доступные в Интернете, а не локальные пути, поэтому вам может потребоваться изменить их.
Конечно, вы можете делать все это только в PHP, поэтому вам нужно создать расширение Twig, чтобы вы могли использовать его в своем шаблоне.
Я удивлен, что в Symfony нет лучшего способа сделать это - я бы хотел знать, если он есть.
Полный код (для использования в методе расширения Twig https://symfony.com/doc/current/templating/twig_extension.html или просто передайте $css в свой шаблон):
$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));
}
Спасибо!. К счастью, я нашел очень похожий обходной путь через несколько дней после публикации этого вопроса, добавленный к моему вопросу.
Круто, да, я подумал, что вы, наверное, уже разобрали это :) Надеюсь, ответ поможет кому-то другому
Также вы можете отключить управление версиями для определенного файла css (email.css) с помощью Encore множественная конфигурация
Что-то вроде этого в вашем webpack.config.js:
Encore
.setOutputPath('public/build/email')
.setPublicPath('/build/email')
.cleanupOutputBeforeBuild()
.disableSingleRuntimeChunk()
.enableBuildNotifications()
.enableSassLoader()
.addStyleEntry('emails', './assets/css/email.scss')
.enableSourceMaps(!Encore.isProduction())
;
затем webpack_encore.yaml
webpack_encore:
output_path: '%kernel.project_dir%/public/build'
builds:
frontend: '%kernel.project_dir%/public/build'
emails: '%kernel.project_dir%/public/build/email'
и, наконец, ваш шаблон электронного письма:
<style>
{{ source('@public/build/email.css') }}
</style>
В конфигурации вашего веб-пакета вы говорите о файлах JS ("только для app.js"), но ваша проблема заключается в управлении версиями css, верно? У вас есть запись для css?