自定义 Symfony2 过滤器未使用自定义树枝标签触发
Posted
技术标签:
【中文标题】自定义 Symfony2 过滤器未使用自定义树枝标签触发【英文标题】:Custom Symfony2 filter not triggering with custom twig tag 【发布时间】:2015-03-14 06:34:36 【问题描述】:TL:DR; 添加type="application/dart"
使Assetic 忽略过滤器标志filter=MyCustomFilter
。
删除后一个属性类型触发filter=MyCustomFilter
就好了。但我需要过滤器和属性。如何让 Assetic 在具有 type=application/dart
属性时触发我的自定义过滤器?
我相信部分问题在于它只接受type=application/javascript
或空的html type
属性来触发过滤器。我不知道从这里去哪里。
详细信息:
我想制作一个类似于javascripts
的标签,但用于 Dart 文件。
% darts
'@AcmeBundle/Resources/dart/AcmeMain/web/main.dart'
%$
<script type="application/dart" src=" asset_url "></script>
% enddarts %
我希望能够使用@
表示法而不是/bundles/etc/
经过一番搜索,我尝试了以下方法:
我扩展了Symfony\Bundle\AsseticBundle\Twig\AsseticExtension
我继承了以下函数:
public function getTokenParsers()
return array(
$this->createTokenParser('javascripts', 'js/*.js'),
$this->createTokenParser('stylesheets', 'css/*.css'),
$this->createTokenParser('image', 'images/*', true),
);
在我自己的子类中,我添加到父数组$this->createTokenParser('darts', 'dart/*.dart')
。
当我有的时候,这最初是有效的。
% darts '@MyBundle\...\main.dart' filter="MyCustomFilter" %
<script src=" asset_url "></script>
但是,引导加载程序 dart.js
需要 type="application/dart
属性才能使引导程序正常工作。
只要我添加了所需的属性,编辑源文件就不会重新编译。它几乎被忽略了。以下代码被忽略,不会触发MyCustomFilter
过滤器:
% darts '@MyBundle\...\main.dart' filter="MyCustomFilter" %
<script type="application/dart" src=" asset_url "></script>
我似乎无法从这里找到下一步该去哪里,看看这一切是如何运作的本身就让人难以抗拒。我只需要将type="application/dart
识别为有效,这样我的MyCustomFilter
就会被触发。
【问题讨论】:
你看twig.sensiolabs.org/doc/advanced.html#tags了吗? 为什么不直接使用% javascripts %
标签和 dart2js 过滤器呢?这样,您的 Dart 脚本将被编译为 JavaScript,避免与浏览器的兼容性问题。
@Nic 如果没有以.dart
结尾的文件名,dartbootloader 将无法工作。我可以修改引导加载程序,但每次更新引导加载程序时,我都必须记住在我的代码工作之前修改引导加载程序。这就是为什么我想要一个合适的解决方案。
我没有使用 Dart 的经验,但是将其编译为普通的旧 javascript 是否不需要客户端编译?
@Nic 从来没有任何客户端编译,飞镖代码在服务器上编译为 javascript。无论如何,它的工作方式是飞镖引导加载程序dart.js
检查未编译的main.dart
。如果浏览器不支持它,它会加载main.js
。现在,在资产的某个地方,当type="application/dart
添加到<script>
属性中时,它会阻止我的过滤器触发编译代码。所以引导加载程序无法加载main.js
,因为assetic 从一开始就没有编译过。
【参考方案1】:
我建议您查看 vendor/symfony/assetic-bundle/
文件,因为它包含 % javascripts %
实现。
从那个包的Resources/config/templating_twig.yml
,他们注入了一个名为@templating.name_parser
的服务,看起来这正是你要找的。p>
您可以尝试在控制器中执行以下操作:
var_dump(
$this
->get('templating.name_parser')
->parse('@AcmeBundle/Resources/dart/AcmeMain/web/main.dart')
->getPath()
);
关于标签本身,您可以从资产包中大量复制/粘贴。并在我之前的一个答案here 上获得一些关于自定义标签的解释。
【讨论】:
我走近了,但不幸的是我偶然发现了另一个障碍。我用更多细节更新了我的答案。 在授予赏金之前,您介意最后看一下我更新的答案吗?我会很感激的。 嗨,我明天早上会检查一下。抱歉,这周没有太多时间。 嗯,你的问题看起来是飞镖特有的,而不是树枝,我真的不知道飞镖。asset_url
s 在渲染视图中是否有效?
如果不是application/javascript
,twig 似乎不会触发过滤器。所以它不是特定于飞镖的。我似乎找不到在哪里可以更改它以允许 application/dart
触发资产过滤器【参考方案2】:
我认为有一个非常简单的解决方案可以解决您的问题,无需使用新的% darts %
标签。
在 Assetic 标签中,您可以指定 output
参数,该参数允许您覆盖默认输出路径(在 % javascripts %
标签的情况下为 js/*.js
)。通过将output
设置为dart/*.dart
,您不仅可以更改存储文件的目录,还可以更改文件扩展名。
例子:
% javascripts '@AcmeBundle/Resources/dart/AcmeMain/web/main.dart' filter="MyCustomFilter" output='dart/*.dart' %
<script type="application/dart" src=" asset_url "></script>
% endjavascripts %
将(在生产环境中)导致:
<script type="application/dart" src="/dart/0b13818.dart"></script>
这个特性在 Symfony 文档中被描述为here,虽然它没有提到你可以改变扩展的事实。
我刚刚在我的 Symfony 应用程序中运行了一个快速测试,它似乎运行良好。
【讨论】:
我以为我试过了,但它最终将其重命名为.dart.js
... 我会再试一次。我认为我没有使用通配符,所以我想知道这是否会有所不同。
应该没什么区别。 dart/foobar.dart
和 dart/*.dart
我都试过了,它们都生成了带有 .dart
扩展名的文件。
好的,谢谢。等我有空工作的时候我会试试的。顺便问一下,你的composer.json
文件中的 Symfony 和 Assetic 是什么版本?
我目前已经安装了 Symfony 2.6.3、Assetic 1.2.1 和 AsseticBundle 2.5.0。 composer.json
需要 Symfony 和 AsseticBundle,两者都具有版本约束 ~2.5
。 Assetic 库作为 AsseticBundle 的依赖项自动安装。
我确认这很好用(在 2.5 到 2.7-dev 上检查)+1。以上是关于自定义 Symfony2 过滤器未使用自定义树枝标签触发的主要内容,如果未能解决你的问题,请参考以下文章