我使用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>
答案 0 :(得分:1)
虽然这不能回答标题中的问题,但可以让您从webpack生成的文件中获取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。请记住,尽管该文件中的路径是可通过Web访问的路径,而不是本地路径,所以您可能需要操纵它们。
当然,您只能在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));
}
答案 1 :(得分:0)
不确定这是否是一个好的解决方案,但是您可以尝试添加ignore-loader plugin并匹配文件以忽略它们,例如webpack.config.js
中的文件忽略所有.css文件
module.exports = {
// ... other configurations ...
module: {
loaders: [
{ test: /\.css$/, loader: 'ignore-loader' }
]
}
};
答案 2 :(得分:0)
您还可以使用Encore multiple config禁用某些CSS文件(email.css)的版本控制
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>