如何对一个特定的文件扩展应用Assetic过滤器

3.4 版本
维护中的版本

从Symfony 2.8开始,Assetic已不再是Symofny标准版框架的自带内容。参考这篇文章以了解如何在你的程序中安装和开启Assetic。

Assetic filters(过滤器)可以被用在独立文件中,文件群组中,甚至,你将在这里看到,一个拥有特殊扩展名的文件中。为了向你展示如何处理每一种选择,假设你希望使用Assetic的CoffeeScript过滤器,它可以把把CoffeeScript文件编译为JavaScript。

主力配置文件中只有 coffee, nodenode_modules 的路径。一个配置示例可能像下面这样:

1
2
3
4
5
6
7
# app/config/config.yml
assetic:
    filters:
        coffee:
            bin:        /usr/bin/coffee
            node:       /usr/bin/node
            node_paths: [/usr/lib/node_modules/]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:assetic="http://symfony.com/schema/dic/assetic"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/assetic
        http://symfony.com/schema/dic/assetic/assetic-1.0.xsd">
 
    <assetic:config>
        <assetic:filter
            name="coffee"
            bin="/usr/bin/coffee/"
            node="/usr/bin/node/">
            <assetic:node-path>/usr/lib/node_modules/</assetic:node-path>
        </assetic:filter>
    </assetic:config>
</container>
1
2
3
4
5
6
7
8
9
10
// app/config/config.php
$container->loadFromExtension('assetic', array(
    'filters' => array(
        'coffee' => array(
            'bin'  => '/usr/bin/coffee',
            'node' => '/usr/bin/node',
            'node_paths' => array('/usr/lib/node_modules/'),
        ),
    ),
));

过滤一个文件 

你现在可以在模板中提供一个单一的CoffeeScript文件作为Javascript:

1
2
3
{% javascripts '@AppBundle/Resources/public/js/example.coffee' filter='coffee' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %}
1
2
3
4
5
6
<?php foreach ($view['assetic']->javascripts(
    array('@AppBundle/Resources/public/js/example.coffee'),
    array('coffee')
) as $url): ?>
    <script src="<?php echo $view->escape($url) ?>"></script>
<?php endforeach ?>

过滤多个文件 

你也可以把多个CoffeeScript文件合并成一个单一文件输出:

1
2
3
4
5
{% javascripts '@AppBundle/Resources/public/js/example.coffee'
               '@AppBundle/Resources/public/js/another.coffee'
    filter='coffee' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %}
1
2
3
4
5
6
7
8
9
<?php foreach ($view['assetic']->javascripts(
    array(
        '@AppBundle/Resources/public/js/example.coffee',
        '@AppBundle/Resources/public/js/another.coffee',
    ),
    array('coffee')
) as $url): ?>
    <script src="<?php echo $view->escape($url) ?>"></script>
<?php endforeach ?>

两个文件现在被当成一个文件给编译成常规JavaScript了。

基于文件扩展名进行过滤 

使用Assetic一个非常先进的地方在于,减少资源数量,降低HTTP请求(开销)。为了充分利用此一点,把你的所有JavaScript或CoffeeScript文件整到一起是个好主意,因为它们最终都会变成JavaScript。不幸的是,只添加JS文件到前述的待合并文件,是不会工作的,因为常规JavaScript文件不能在CoffeeScript编译过程中存活。

通过使用 apply_to 选项可以避免此问题,它能让你指定“对一个特定文件扩展,始终使用哪个过滤器”。本例你可以指定 coffee filter将被应用到全部 .coffee 文件:

1
2
3
4
5
6
7
8
# app/config/config.yml
assetic:
    filters:
        coffee:
            bin:        /usr/bin/coffee
            node:       /usr/bin/node
            node_paths: [/usr/lib/node_modules/]
            apply_to:   '\.coffee$'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:assetic="http://symfony.com/schema/dic/assetic"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/assetic
        http://symfony.com/schema/dic/assetic/assetic-1.0.xsd">
 
    <assetic:config>
        <assetic:filter
            name="coffee"
            bin="/usr/bin/coffee"
            node="/usr/bin/node"
            apply_to="\.coffee$" />
            <assetic:node-paths>/usr/lib/node_modules/</assetic:node-path>
    </assetic:config>
</container>
1
2
3
4
5
6
7
8
9
10
11
// app/config/config.php
$container->loadFromExtension('assetic', array(
    'filters' => array(
        'coffee' => array(
            'bin'      => '/usr/bin/coffee',
            'node'     => '/usr/bin/node',
            'node_paths' => array('/usr/lib/node_modules/'),
            'apply_to' => '\.coffee$',
        ),
    ),
));

有了这个选项,在模板中你不再需要指定 coffee 过滤器。你还能列出全部常规JavaScript文件,它们都将被合并,且以一个单一JavaScript文件输出(只有 .coffee 文件才会使用CoffeeScript过滤器)。

1
2
3
4
5
{% javascripts '@AppBundle/Resources/public/js/example.coffee'
               '@AppBundle/Resources/public/js/another.coffee'
               '@AppBundle/Resources/public/js/regular.js' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %}
1
2
3
4
5
6
7
8
9
<?php foreach ($view['assetic']->javascripts(
    array(
        '@AppBundle/Resources/public/js/example.coffee',
        '@AppBundle/Resources/public/js/another.coffee',
        '@AppBundle/Resources/public/js/regular.js',
    )
) as $url): ?>
    <script src="<?php echo $view->escape($url) ?>"></script>
<?php endforeach ?>

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)