Ver código fonte

Merge remote branch 'kriswallsmith/assetic/explicit-filter-config'

* kriswallsmith/assetic/explicit-filter-config:
  [AsseticBundle] added lessphp filter
  [AsseticBundle] added config for image filters
  [AsseticBundle] moved filters into individual config files which must be explicitly loaded
  [AsseticBundle] removed configuration of default output strings
Fabien Potencier 14 anos atrás
pai
commit
d44c184d57
25 arquivos alterados com 461 adições e 106 exclusões
  1. 4 0
      src/Symfony/Bundle/AsseticBundle/AsseticBundle.php
  2. 23 15
      src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php
  3. 33 0
      src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php
  4. 36 0
      src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckYuiFilterPass.php
  5. 18 7
      src/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php
  6. 9 58
      src/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml
  7. 25 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/closure.xml
  8. 20 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/coffee.xml
  9. 6 4
      src/Symfony/Bundle/AsseticBundle/Resources/config/google_closure_compiler.xml
  10. 18 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/jepgtran.xml
  11. 18 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegoptim.xml
  12. 21 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/less.xml
  13. 17 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/lessphp.xml
  14. 18 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/optipng.xml
  15. 18 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/pngout.xml
  16. 18 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/sass.xml
  17. 18 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/scss.xml
  18. 19 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/sprockets.xml
  19. 21 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/stylus.xml
  20. 4 8
      src/Symfony/Bundle/AsseticBundle/Resources/config/yui_compressor.xml
  21. 20 0
      src/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_js.xml
  22. 11 3
      src/Symfony/Bundle/AsseticBundle/Resources/config/schema/assetic-1.0.xsd
  23. 0 2
      src/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml
  24. 0 2
      src/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml
  25. 66 7
      src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php

+ 4 - 0
src/Symfony/Bundle/AsseticBundle/AsseticBundle.php

@@ -13,7 +13,9 @@ namespace Symfony\Bundle\AsseticBundle;
 
 use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\AssetFactoryPass;
 use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\AssetManagerPass;
+use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\CheckYuiFilterPass;
 use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\FilterManagerPass;
+use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\CheckClosureFilterPass;
 use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\TemplatingPass;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\HttpKernel\Bundle\Bundle;
@@ -29,6 +31,8 @@ class AsseticBundle extends Bundle
     {
         parent::build($container);
 
+        $container->addCompilerPass(new CheckClosureFilterPass());
+        $container->addCompilerPass(new CheckYuiFilterPass());
         $container->addCompilerPass(new TemplatingPass());
         $container->addCompilerPass(new AssetFactoryPass());
         $container->addCompilerPass(new AssetManagerPass());

+ 23 - 15
src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php

@@ -34,6 +34,8 @@ class AsseticExtension extends Extension
      */
     public function load(array $configs, ContainerBuilder $container)
     {
+        $parameterBag = $container->getParameterBag();
+
         $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
         $loader->load('assetic.xml');
         $loader->load('templating_twig.xml');
@@ -45,20 +47,29 @@ class AsseticExtension extends Extension
         $container->setParameter('assetic.use_controller', $config['use_controller']);
         $container->setParameter('assetic.read_from', $config['read_from']);
         $container->setParameter('assetic.write_to', $config['write_to']);
-        $container->setParameter('assetic.default_javascripts_output', $config['default_javascripts_output']);
-        $container->setParameter('assetic.default_stylesheets_output', $config['default_stylesheets_output']);
 
-        if (isset($config['closure'])) {
-            $container->setParameter('assetic.google_closure_compiler_jar', $config['closure']);
-            $loader->load('google_closure_compiler.xml');
-        }
+        $container->setParameter('assetic.closure.jar', $config['closure']);
+        $container->setParameter('assetic.java.bin', $config['java']);
+        $container->setParameter('assetic.node.bin', $config['node']);
+        $container->setParameter('assetic.sass.bin', $config['sass']);
+        $container->setParameter('assetic.yui.jar', $config['yui']);
+
+        // register filters
+        foreach ($config['filters'] as $name => $filter) {
+            if (isset($filter['resource'])) {
+                $loader->load($parameterBag->resolveValue($filter['resource']));
+                unset($filter['resource']);
+            } else {
+                $loader->load('filters/'.$name.'.xml');
+            }
 
-        if (isset($config['yui'])) {
-            $container->setParameter('assetic.yui_jar', $config['yui']);
-            $loader->load('yui_compressor.xml');
+            foreach ($filter as $key => $value) {
+                $container->setParameter('assetic.filter.'.$name.'.'.$key, $value);
+            }
         }
 
-        if ($container->getParameterBag()->resolveValue($container->getParameterBag()->get('assetic.use_controller'))) {
+        // choose dynamic or static
+        if ($parameterBag->resolveValue($parameterBag->get('assetic.use_controller'))) {
             $loader->load('controller.xml');
             $container->setParameter('assetic.twig_extension.class', '%assetic.twig_extension.dynamic.class%');
         } else {
@@ -66,11 +77,8 @@ class AsseticExtension extends Extension
             $container->setParameter('assetic.twig_extension.class', '%assetic.twig_extension.static.class%');
         }
 
-        if ($container->hasParameter('assetic.less.compress')) {
-            $container->getDefinition('assetic.filter.less')->addMethodCall('setCompress', array('%assetic.less.compress%'));
-        }
-
-        $this->registerFormulaResources($container, $container->getParameterBag()->resolveValue($config['bundles']));
+        // register config resources
+        self::registerFormulaResources($container, $parameterBag->resolveValue($config['bundles']));
     }
 
     static protected function processConfigs(array $configs, $debug, array $bundles)

+ 33 - 0
src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php

@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Tags either the closure JAR or API filter for the filter manager.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@symfony.com>
+ */
+class CheckClosureFilterPass implements CompilerPassInterface
+{
+    public function process(ContainerBuilder $container)
+    {
+        if ($container->hasDefinition('assetic.filter.closure.jar') &&
+            $container->getParameterBag()->resolveValue($container->getParameter('assetic.filter.closure.jar'))) {
+            $container->remove('assetic.filter.closure.api');
+        } elseif ($container->hasDefinition('assetic.filter.closure.api')) {
+            $container->remove('assetic.filter.closure.jar');
+        }
+    }
+}

+ 36 - 0
src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckYuiFilterPass.php

@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Checks that the location of the YUI JAR has been configured.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@symfony.com>
+ */
+class CheckYuiFilterPass implements CompilerPassInterface
+{
+    public function process(ContainerBuilder $container)
+    {
+        if ($container->hasDefinition('assetic.filter.yui_css') &&
+            !$container->getParameterBag()->resolveValue($container->getParameter('assetic.filter.yui_css.jar'))) {
+            throw new \RuntimeException('The Assetic "yui_css" configuration requires a "jar" value.');
+        }
+
+        if ($container->hasDefinition('assetic.filter.yui_js') &&
+            !$container->getParameterBag()->resolveValue($container->getParameter('assetic.filter.yui_js.jar'))) {
+            throw new \RuntimeException('The Assetic "yui_js" configuration requires a "jar" value.');
+        }
+    }
+}

+ 18 - 7
src/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php

@@ -20,6 +20,7 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder;
  * sections are normalized, and merged.
  *
  * @author Christophe Coevoet <stof@notk.org>
+ * @author Kris Wallsmith <kris@symfony.com>
  */
 class Configuration
 {
@@ -41,10 +42,11 @@ class Configuration
                 ->booleanNode('use_controller')->defaultValue($debug)->end()
                 ->scalarNode('read_from')->defaultValue('%kernel.root_dir%/../web')->end()
                 ->scalarNode('write_to')->defaultValue('%assetic.read_from%')->end()
-                ->scalarNode('closure')->end()
-                ->scalarNode('yui')->end()
-                ->scalarNode('default_javascripts_output')->defaultValue('js/*.js')->end()
-                ->scalarNode('default_stylesheets_output')->defaultValue('css/*.css')->end()
+                ->scalarNode('closure')->defaultNull()->end()
+                ->scalarNode('java')->defaultNull()->end()
+                ->scalarNode('node')->defaultNull()->end()
+                ->scalarNode('sass')->defaultNull()->end()
+                ->scalarNode('yui')->defaultNull()->end()
             ->end()
             ->fixXmlConfig('bundle')
             ->children()
@@ -52,17 +54,26 @@ class Configuration
                     ->defaultValue($bundles)
                     ->requiresAtLeastOneElement()
                     ->beforeNormalization()
-                        ->ifTrue(function($v){ return !is_array($v); })
-                        ->then(function($v){ return array($v); })
+                        ->ifTrue(function($v) { return !is_array($v); })
+                        ->then(function($v) { return array($v); })
                     ->end()
                     ->prototype('scalar')
                         ->beforeNormalization()
                             ->ifTrue(function($v) { return is_array($v) && isset($v['name']); })
-                            ->then(function($v){ return $v['name']; })
+                            ->then(function($v) { return $v['name']; })
                         ->end()
                     ->end()
                 ->end()
             ->end()
+            ->fixXmlConfig('filter')
+            ->children()
+                ->arrayNode('filters')
+                    ->addDefaultsIfNotSet()
+                    ->requiresAtLeastOneElement()
+                    ->useAttributeAsKey('name')
+                    ->prototype('array')->end()
+                ->end()
+            ->end()
         ;
 
         return $tree->buildTree();

+ 9 - 58
src/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml

@@ -7,28 +7,18 @@
     <parameters>
         <parameter key="assetic.asset_factory.class">Symfony\Bundle\AsseticBundle\Factory\AssetFactory</parameter>
         <parameter key="assetic.asset_manager.class">Assetic\Factory\LazyAssetManager</parameter>
-        <parameter key="assetic.filter_manager.class">Symfony\Bundle\AsseticBundle\FilterManager</parameter>
+        <parameter key="assetic.asset_manager_cache_warmer.class">Symfony\Bundle\AsseticBundle\CacheWarmer\AssetManagerCacheWarmer</parameter>
         <parameter key="assetic.cached_formula_loader.class">Assetic\Factory\Loader\CachedFormulaLoader</parameter>
         <parameter key="assetic.config_cache.class">Assetic\Cache\ConfigCache</parameter>
-        <parameter key="assetic.asset_manager_cache_warmer.class">Symfony\Bundle\AsseticBundle\CacheWarmer\AssetManagerCacheWarmer</parameter>
         <parameter key="assetic.directory_resource.class">Symfony\Bundle\AsseticBundle\Factory\Resource\DirectoryResource</parameter>
+        <parameter key="assetic.filter_manager.class">Symfony\Bundle\AsseticBundle\FilterManager</parameter>
 
-        <parameter key="assetic.filter.coffee.class">Assetic\Filter\CoffeeScriptFilter</parameter>
-        <parameter key="assetic.filter.cssrewrite.class">Assetic\Filter\CssRewriteFilter</parameter>
-        <parameter key="assetic.filter.google_closure_compiler_api.class">Assetic\Filter\GoogleClosure\CompilerApiFilter</parameter>
-        <parameter key="assetic.filter.google_closure_compiler_jar.class">Assetic\Filter\GoogleClosure\CompilerJarFilter</parameter>
-        <parameter key="assetic.filter.less.class">Assetic\Filter\LessFilter</parameter>
-        <parameter key="assetic.filter.sass.class">Assetic\Filter\Sass\SassFilter</parameter>
-        <parameter key="assetic.filter.scss.class">Assetic\Filter\Sass\ScssFilter</parameter>
-        <parameter key="assetic.filter.sprockets.class">Assetic\Filter\SprocketsFilter</parameter>
-        <parameter key="assetic.filter.stylus.class">Assetic\Filter\StylusFilter</parameter>
-
-        <parameter key="assetic.java_bin">/usr/bin/java</parameter>
-        <parameter key="assetic.sass_bin">/usr/bin/sass</parameter>
-        <parameter key="assetic.node_bin">/usr/bin/node</parameter>
-        <parameter key="assetic.node_paths" type="collection"></parameter>
-        <parameter key="assetic.sprocketize_bin">/usr/bin/sprocketize</parameter>
-        <parameter key="assetic.coffee_bin">/usr/bin/coffee</parameter>
+        <parameter key="assetic.closure.jar" />
+        <parameter key="assetic.java.bin">/usr/bin/java</parameter>
+        <parameter key="assetic.node.bin">/usr/bin/node</parameter>
+        <parameter key="assetic.node.paths" type="collection"></parameter>
+        <parameter key="assetic.sass.bin">/usr/bin/sass</parameter>
+        <parameter key="assetic.yui.jar" />
 
         <parameter key="assetic.cache_dir">%kernel.cache_dir%/assetic</parameter>
     </parameters>
@@ -43,52 +33,13 @@
             <argument type="service" id="assetic.asset_factory" />
             <argument type="collection"></argument>
         </service>
+
         <service id="assetic.asset_factory" class="%assetic.asset_factory.class%" public="false">
             <argument type="service" id="kernel" />
             <argument>%assetic.read_from%</argument>
             <argument>%assetic.debug%</argument>
             <call method="setFilterManager"><argument type="service" id="assetic.filter_manager" /></call>
         </service>
-
-        <!-- filters -->
-        <service id="assetic.filter.cssrewrite" class="%assetic.filter.cssrewrite.class%">
-            <tag name="assetic.filter" alias="cssrewrite" />
-        </service>
-        <service id="assetic.filter.less" class="%assetic.filter.less.class%">
-            <tag name="assetic.filter" alias="less" />
-            <argument>%assetic.read_from%</argument>
-            <argument>%assetic.node_bin%</argument>
-            <argument>%assetic.node_paths%</argument>
-        </service>
-        <service id="assetic.filter.sass" class="%assetic.filter.sass.class%">
-            <tag name="assetic.filter" alias="sass" />
-            <argument>%assetic.sass_bin%</argument>
-        </service>
-        <service id="assetic.filter.scss" class="%assetic.filter.scss.class%">
-            <tag name="assetic.filter" alias="scss" />
-            <argument>%assetic.sass_bin%</argument>
-        </service>
-        <service id="assetic.filter.google_closure_compiler" class="%assetic.filter.google_closure_compiler_api.class%">
-            <tag name="assetic.filter" alias="closure" />
-        </service>
-        <service id="assetic.filter.sprockets" class="%assetic.filter.sprockets.class%">
-            <tag name="assetic.filter" alias="sprockets" />
-            <argument>%assetic.read_from%</argument>
-            <argument>%assetic.sprocketize_bin%</argument>
-        </service>
-        <service id="assetic.filter.coffee" class="%assetic.filter.coffee.class%">
-            <tag name="assetic.filter" alias="coffee" />
-            <argument>%assetic.coffee_bin%</argument>
-            <argument>%assetic.node_bin%</argument>
-        </service>
-        <service id="assetic.filter.stylus" class="%assetic.filter.stylus.class%">
-            <tag name="assetic.filter" alias="stylus" />
-            <argument>%assetic.read_from%</argument>
-            <argument>%assetic.node_bin%</argument>
-            <argument>%assetic.node_paths%</argument>
-        </service>
-
-        <!-- other -->
         <service id="assetic.config_cache" class="%assetic.config_cache.class%" public="false">
             <argument>%assetic.cache_dir%/config</argument>
         </service>

+ 25 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/closure.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.closure.api.class">Assetic\Filter\GoogleClosure\CompilerApiFilter</parameter>
+        <parameter key="assetic.filter.closure.jar.class">Assetic\Filter\GoogleClosure\CompilerJarFilter</parameter>
+        <parameter key="assetic.filter.closure.java">%assetic.java.bin%</parameter>
+        <parameter key="assetic.filter.closure.jar">%assetic.closure.jar%</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.closure.jar" class="%assetic.filter.closure.jar.class%">
+            <tag name="assetic.filter" alias="closure" />
+            <argument>%assetic.filter.closure.jar%</argument>
+            <argument>%assetic.filter.closure.java%</argument>
+        </service>
+
+        <service id="assetic.filter.closure.api" class="%assetic.filter.closure.api.class%">
+            <tag name="assetic.filter" alias="closure" />
+        </service>
+    </services>
+</container>

+ 20 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/coffee.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.coffee.class">Assetic\Filter\CoffeeScriptFilter</parameter>
+        <parameter key="assetic.filter.coffee.bin">/usr/bin/coffee</parameter>
+        <parameter key="assetic.filter.coffee.node">%assetic.node.bin%</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.coffee" class="%assetic.filter.coffee.class%">
+            <tag name="assetic.filter" alias="coffee" />
+            <argument>%assetic.filter.coffee.bin%</argument>
+            <argument>%assetic.filter.coffee.node%</argument>
+        </service>
+    </services>
+</container>

+ 6 - 4
src/Symfony/Bundle/AsseticBundle/Resources/config/google_closure_compiler.xml

@@ -4,11 +4,13 @@
     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">
 
+    <parameters>
+        <parameter key="assetic.filter.cssrewrite.class">Assetic\Filter\CssRewriteFilter</parameter>
+    </parameters>
+
     <services>
-        <service id="assetic.filter.google_closure_compiler" class="%assetic.filter.google_closure_compiler_jar.class%">
-            <tag name="assetic.filter" alias="closure" />
-            <argument>%assetic.google_closure_compiler_jar%</argument>
-            <argument>%assetic.java_bin%</argument>
+        <service id="assetic.filter.cssrewrite" class="%assetic.filter.cssrewrite.class%">
+            <tag name="assetic.filter" alias="cssrewrite" />
         </service>
     </services>
 </container>

+ 18 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/jepgtran.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.jpegtran.class">Assetic\Filter\JpegtranFilter</parameter>
+        <parameter key="assetic.filter.jpegtran.bin">/usr/bin/jpegtran</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.jpegtran" class="%assetic.filter.jpegtran.class%">
+            <tag name="assetic.filter" alias="jpegtran" />
+            <argument>%assetic.filter.jpegtran.bin%</argument>
+        </service>
+    </services>
+</container>

+ 18 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/jpegoptim.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.jpegoptim.class">Assetic\Filter\JpegoptimFilter</parameter>
+        <parameter key="assetic.filter.jpegoptim.bin">/usr/bin/jpegoptim</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.jpegoptim" class="%assetic.filter.jpegoptim.class%">
+            <tag name="assetic.filter" alias="jpegoptim" />
+            <argument>%assetic.filter.jpegoptim.bin%</argument>
+        </service>
+    </services>
+</container>

+ 21 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/less.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.less.class">Assetic\Filter\LessFilter</parameter>
+        <parameter key="assetic.filter.less.node">%assetic.node.bin%</parameter>
+        <parameter key="assetic.filter.less.node_paths">%assetic.node.paths%</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.less" class="%assetic.filter.less.class%">
+            <tag name="assetic.filter" alias="less" />
+            <argument>%assetic.read_from%</argument>
+            <argument>%assetic.filter.less.node%</argument>
+            <argument>%assetic.filter.less.node_paths%</argument>
+        </service>
+    </services>
+</container>

+ 17 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/lessphp.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.lessphp.class">Assetic\Filter\LessphpFilter</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.lessphp" class="%assetic.filter.lessphp.class%">
+            <tag name="assetic.filter" alias="lessphp" />
+            <argument>%assetic.read_from%</argument>
+        </service>
+    </services>
+</container>

+ 18 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/optipng.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.optipng.class">Assetic\Filter\OptiPngFilter</parameter>
+        <parameter key="assetic.filter.optipng.bin">/usr/bin/optipng</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.optipng" class="%assetic.filter.optipng.class%">
+            <tag name="assetic.filter" alias="optipng" />
+            <argument>%assetic.filter.optipng.bin%</argument>
+        </service>
+    </services>
+</container>

+ 18 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/pngout.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.pngout.class">Assetic\Filter\PngoutFilter</parameter>
+        <parameter key="assetic.filter.pngout.bin">/usr/bin/pngout</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.pngout" class="%assetic.filter.pngout.class%">
+            <tag name="assetic.filter" alias="pngout" />
+            <argument>%assetic.filter.pngout.bin%</argument>
+        </service>
+    </services>
+</container>

+ 18 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/sass.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.sass.class">Assetic\Filter\Sass\SassFilter</parameter>
+        <parameter key="assetic.filter.sass.bin">%assetic.sass.bin%</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.sass" class="%assetic.filter.sass.class%">
+            <tag name="assetic.filter" alias="sass" />
+            <argument>%assetic.filter.sass.bin%</argument>
+        </service>
+    </services>
+</container>

+ 18 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/scss.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.scss.class">Assetic\Filter\Sass\ScssFilter</parameter>
+        <parameter key="assetic.filter.scss.sass">%assetic.sass.bin%</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.scss" class="%assetic.filter.scss.class%">
+            <tag name="assetic.filter" alias="scss" />
+            <argument>%assetic.filter.scss.sass%</argument>
+        </service>
+    </services>
+</container>

+ 19 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/sprockets.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.sprockets.class">Assetic\Filter\SprocketsFilter</parameter>
+        <parameter key="assetic.filter.sprockets.bin">/usr/bin/sprocketize</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.sprockets" class="%assetic.filter.sprockets.class%">
+            <tag name="assetic.filter" alias="sprockets" />
+            <argument>%assetic.read_from%</argument>
+            <argument>%assetic.filter.sprockets.bin%</argument>
+        </service>
+    </services>
+</container>

+ 21 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/stylus.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.stylus.class">Assetic\Filter\StylusFilter</parameter>
+        <parameter key="assetic.filter.stylus.node">%assetic.node.bin%</parameter>
+        <parameter key="assetic.filter.stylus.node_paths">%assetic.node.paths%</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.stylus" class="%assetic.filter.stylus.class%">
+            <tag name="assetic.filter" alias="stylus" />
+            <argument>%assetic.read_from%</argument>
+            <argument>%assetic.filter.stylus.node%</argument>
+            <argument>%assetic.filter.stylus.node_paths%</argument>
+        </service>
+    </services>
+</container>

+ 4 - 8
src/Symfony/Bundle/AsseticBundle/Resources/config/yui_compressor.xml

@@ -6,19 +6,15 @@
 
     <parameters>
         <parameter key="assetic.filter.yui_css.class">Assetic\Filter\Yui\CssCompressorFilter</parameter>
-        <parameter key="assetic.filter.yui_js.class">Assetic\Filter\Yui\JsCompressorFilter</parameter>
+        <parameter key="assetic.filter.yui_css.java">%assetic.java.bin%</parameter>
+        <parameter key="assetic.filter.yui_css.jar">%assetic.yui.jar%</parameter>
     </parameters>
 
     <services>
         <service id="assetic.filter.yui_css" class="%assetic.filter.yui_css.class%">
             <tag name="assetic.filter" alias="yui_css" />
-            <argument>%assetic.yui_jar%</argument>
-            <argument>%assetic.java_bin%</argument>
-        </service>
-        <service id="assetic.filter.yui_js" class="%assetic.filter.yui_js.class%">
-            <tag name="assetic.filter" alias="yui_js" />
-            <argument>%assetic.yui_jar%</argument>
-            <argument>%assetic.java_bin%</argument>
+            <argument>%assetic.filter.yui_css.jar%</argument>
+            <argument>%assetic.filter.yui_css.java%</argument>
         </service>
     </services>
 </container>

+ 20 - 0
src/Symfony/Bundle/AsseticBundle/Resources/config/filters/yui_js.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+    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">
+
+    <parameters>
+        <parameter key="assetic.filter.yui_js.class">Assetic\Filter\Yui\JsCompressorFilter</parameter>
+        <parameter key="assetic.filter.yui_js.java">%assetic.java.bin%</parameter>
+        <parameter key="assetic.filter.yui_js.jar">%assetic.yui.jar%</parameter>
+    </parameters>
+
+    <services>
+        <service id="assetic.filter.yui_js" class="%assetic.filter.yui_js.class%">
+            <tag name="assetic.filter" alias="yui_js" />
+            <argument>%assetic.filter.yui_js.jar%</argument>
+            <argument>%assetic.filter.yui_js.java%</argument>
+        </service>
+    </services>
+</container>

+ 11 - 3
src/Symfony/Bundle/AsseticBundle/Resources/config/schema/assetic-1.0.xsd

@@ -10,18 +10,26 @@
     <xsd:complexType name="config">
         <xsd:sequence>
             <xsd:element name="bundle" type="bundle" minOccurs="0" maxOccurs="unbounded" />
+            <xsd:element name="filter" type="filter" minOccurs="0" maxOccurs="unbounded" />
         </xsd:sequence>
         <xsd:attribute name="debug" type="xsd:string" />
         <xsd:attribute name="use-controller" type="xsd:string" />
         <xsd:attribute name="read-from" type="xsd:string" />
         <xsd:attribute name="write-to" type="xsd:string" />
         <xsd:attribute name="closure" type="xsd:string" />
+        <xsd:attribute name="java" type="xsd:string" />
+        <xsd:attribute name="node" type="xsd:string" />
+        <xsd:attribute name="sass" type="xsd:string" />
         <xsd:attribute name="yui" type="xsd:string" />
-        <xsd:attribute name="default-javascripts-output" type="xsd:string" />
-        <xsd:attribute name="default-stylesheets-output" type="xsd:string" />
     </xsd:complexType>
 
     <xsd:complexType name="bundle">
-        <xsd:attribute name="name" type="xsd:string" />
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+    </xsd:complexType>
+
+    <xsd:complexType name="filter">
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+        <xsd:attribute name="resource" type="xsd:string" />
+        <xsd:anyAttribute namespace="##any" processContents="lax" />
     </xsd:complexType>
 </xsd:schema>

+ 0 - 2
src/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml

@@ -15,8 +15,6 @@
             <tag name="assetic.templating.php" />
             <argument type="service" id="assetic.asset_factory" />
             <argument>%assetic.debug%</argument>
-            <argument>%assetic.default_javascripts_output%</argument>
-            <argument>%assetic.default_stylesheets_output%</argument>
         </service>
         <service id="assetic.php_formula_loader" class="%assetic.cached_formula_loader.class%" public="false">
             <tag name="assetic.formula_loader" alias="php" />

+ 0 - 2
src/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml

@@ -16,8 +16,6 @@
             <tag name="assetic.templating.twig" />
             <argument type="service" id="assetic.asset_factory" />
             <argument>%assetic.debug%</argument>
-            <argument>%assetic.default_javascripts_output%</argument>
-            <argument>%assetic.default_stylesheets_output%</argument>
         </service>
         <service id="assetic.twig_formula_loader" class="%assetic.cached_formula_loader.class%" public="false">
             <tag name="assetic.formula_loader" alias="twig" />

+ 66 - 7
src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php

@@ -12,10 +12,13 @@
 namespace Symfony\Bundle\AsseticBundle\Tests\DependencyInjection;
 
 use Symfony\Bundle\AsseticBundle\DependencyInjection\AsseticExtension;
+use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\CheckYuiFilterPass;
+use Symfony\Bundle\AsseticBundle\DependencyInjection\Compiler\CheckClosureFilterPass;
 use Symfony\Component\DependencyInjection\Container;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
 use Symfony\Component\DependencyInjection\Scope;
+use Symfony\Component\Finder\Finder;
 use Symfony\Component\HttpFoundation\Request;
 
 class AsseticExtensionTest extends \PHPUnit_Framework_TestCase
@@ -81,17 +84,33 @@ class AsseticExtensionTest extends \PHPUnit_Framework_TestCase
         );
     }
 
-    public function testYuiConfig()
+    /**
+     * @dataProvider getFilterNames
+     */
+    public function testFilterConfigs($filter)
     {
-        $extension = new AsseticExtension();
-        $extension->load(array(array('yui' => '/path/to/yuicompressor.jar')), $this->container);
+        $config = array('filters' => array($filter => array()));
 
-        $this->assertTrue($this->container->has('assetic.filter.yui_css'), '->load() loads the yui_css filter when a yui value is provided');
-        $this->assertTrue($this->container->has('assetic.filter.yui_js'), '->load() loads the yui_js filter when a yui value is provided');
+        $extension = new AsseticExtension();
+        $extension->load(array($config), $this->container);
 
         $this->assertSaneContainer($this->getDumpedContainer());
     }
 
+    public function getFilterNames()
+    {
+        $data = array();
+
+        $finder = new Finder();
+        $finder->files()->name('*.xml')->in(__DIR__.'/../../Resources/config/filters');
+
+        foreach ($finder as $file) {
+            $data[] = array($file->getBasename('.xml'));
+        }
+
+        return $data;
+    }
+
     /**
      * @dataProvider getUseControllerKeys
      */
@@ -119,12 +138,52 @@ class AsseticExtensionTest extends \PHPUnit_Framework_TestCase
         );
     }
 
-    public function testClosure()
+    /**
+     * @dataProvider getClosureJarAndExpected
+     */
+    public function testClosureCompilerPass($jar, $expected)
     {
+        $this->container->addCompilerPass(new CheckClosureFilterPass());
+
+        $config = array(
+            'closure' => $jar,
+            'filters' => array(
+                'closure' => array(),
+            ),
+        );
+
         $extension = new AsseticExtension();
-        $extension->load(array(array('closure' => '/path/to/closure.jar')), $this->container);
+        $extension->load(array($config), $this->container);
 
         $this->assertSaneContainer($this->getDumpedContainer());
+
+        $this->assertTrue($this->container->getDefinition($expected)->hasTag('assetic.filter'));
+    }
+
+    public function getClosureJarAndExpected()
+    {
+        return array(
+            array(null, 'assetic.filter.closure.api'),
+            array('/path/to/closure.jar', 'assetic.filter.closure.jar'),
+        );
+    }
+
+    public function testInvalidYuiConfig()
+    {
+        $this->setExpectedException('RuntimeException');
+
+        $this->container->addCompilerPass(new CheckYuiFilterPass());
+
+        $config = array(
+            'filters' => array(
+                'yui_js' => array(),
+            ),
+        );
+
+        $extension = new AsseticExtension();
+        $extension->load(array($config), $this->container);
+
+        $this->getDumpedContainer();
     }
 
     private function getDumpedContainer()