【问题标题】:Custom Symfony2 filter not triggering with custom twig tag自定义 Symfony2 过滤器未使用自定义树枝标签触发
【发布时间】: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-&gt;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 就会被触发。

【问题讨论】:

  • 为什么不直接使用{% javascripts %} 标签和 dart2js 过滤器呢?这样,您的 Dart 脚本将被编译为 JavaScript,避免与浏览器的兼容性问题。
  • @Nic 如果没有以.dart 结尾的文件名,dartbootloader 将无法工作。我可以修改引导加载程序,但每次更新引导加载程序时,我都必须记住在我的代码工作之前修改引导加载程序。这就是为什么我想要一个合适的解决方案。
  • 我没有使用 Dart 的经验,但是将其编译为普通的旧 javascript 是否不需要客户端编译?
  • @Nic 从来没有任何客户端编译,飞镖代码在服务器上编译为 javascript。无论如何,它的工作方式是飞镖引导加载程序dart.js 检查未编译的main.dart。如果浏览器不支持它,它会加载main.js。现在,在资产的某个地方,当type="application/dart 添加到&lt;script&gt; 属性中时,它会阻止我的过滤器触发编译代码。所以引导加载程序无法加载main.js,因为assetic 从一开始就没有编译过。

标签: php symfony dart twig 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_urls 在渲染视图中是否有效?
  • 如果不是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.dartdart/*.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。
猜你喜欢
  • 1970-01-01
  • 2013-09-20
  • 2016-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多