Symfony 如何从版本化的网页包Encore构建中获取CSS作为字符串,以便在电子邮件中使用它?
我用细枝渲染电子邮件 要将CSS直接导入电子邮件,我执行了以下操作:Symfony 如何从版本化的网页包Encore构建中获取CSS作为字符串,以便在电子邮件中使用它?,symfony,twig,webpack-encore,Symfony,Twig,Webpack Encore,我用细枝渲染电子邮件 要将CSS直接导入电子邮件,我执行了以下操作: <style> {{ source('@public/build/email.css') }} </style> 更新:我的解决方案 我编写了一个简单的细枝函数来解决这个问题: <?php namespace App\Twig; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; class AppExtensi
<style>
{{ source('@public/build/email.css') }}
</style>
更新:我的解决方案
我编写了一个简单的细枝函数来解决这个问题:
<?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.');
}
}
不确定这是否是一个好的解决方案,但您可以尝试添加和匹配文件以忽略它们,例如在webpack.config.js
忽略所有.css文件中
module.exports = {
// ... other configurations ...
module: {
loaders: [
{ test: /\.css$/, loader: 'ignore-loader' }
]
}
};
虽然这不能回答标题中的问题,但它可以让您从网页包生成的文件中获取CSS,并将其包含在电子邮件中
Webpack Encore在构建文件夹中创建一个名为“entrypoints.js”的文件。您需要使用$decodedFile=json\u decode(file\u get\u contents('your/build/folder/entrypoints.json'))获取并解析该文件代码>
然后可以作为对象遍历该文件的内容。您需要的文件路径类似于$decodedFile->entrypoints->email->css
,这将为该条目提供一个css文件数组(可以有多个文件,例如,如果您的webpack.config.js文件中有.splitEntryChunks()
方法)
在获得这些内容之后,您需要对该数组中的每个文件执行file\u get\u contents($yourCssFile)
,以从每个文件中获取CSS。请记住,该文件中的路径是可通过web访问的路径,而不是本地路径,因此您可能需要对它们进行操作
当然,您只能在PHP中完成所有这些,因此您需要创建一个细枝扩展,以允许您在模板中使用它
我很惊讶在Symfony没有更好的方法来做到这一点——如果有,我很想知道
完整代码(用于细枝扩展方法,或只需将$css
传递到模板中):
$files=json\u decode(文件获取内容('your/build/folder/entrypoints.json'))
->入口点
->电子邮件
->css
;
$css='';
foreach($files作为$file){
$css.=file_get_contents('your/build/folder/')。basename($file));
}
您还可以使用禁用特定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\u 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>
{{source('@public/build/email.css')}
在您的网页配置中,您谈论的是JS文件(“仅适用于app.JS”),但您的问题在于css版本控制,对吗?你有css的条目吗?嗯,实际上我不确定webpack到底是如何工作的,但我遵循了symfony的教程。我的email.js
文件中包含以下内容:import'../css/email.scss'
事实上,我不理解您的问题,为什么版本控制会影响您的电子邮件模板?{source('@public/build/email.css')}
是一个将文件内容加载到当前模板中的细枝函数。因为我想在我的电子邮件模板中使用SCS,所以我需要配置一个构建过程source
,而不是asset
,不使用manifest.json文件将干净路径转换为版本化路径。因此Twig认为,该文件可以在build/email.css
找到,而实际上它位于build/email.sdf3121.css
我认为您需要使用asset()而不是source(){asset('build/email.css')}谢谢!。幸运的是,在发布这个问题几天后,我发现了一个非常类似的解决方法,添加到我的问题中。酷,是的,我想你现在可能已经把它分类了:)希望这个答案能帮助其他人
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>