From e6d4734d4e4b5d9f161164f9ba4c41094d18b893 Mon Sep 17 00:00:00 2001 From: Kris Wallsmith Date: Fri, 1 Apr 2011 11:57:33 -0700 Subject: [PATCH] [AsseticBundle] cleaned up php templating support --- .../DependencyInjection/AsseticExtension.php | 4 ++ .../Compiler/TemplatingPass.php | 1 - .../Loader/AsseticHelperFormulaLoader.php | 14 +++-- .../Resources/config/templating_php.xml | 16 ++++- .../Templating/AsseticHelper.php | 62 +++++++++---------- .../Templating/DynamicAsseticHelper.php | 45 ++++++++++++++ .../Templating/FormulaLoader.php | 44 ------------- .../Templating/StaticAsseticHelper.php | 45 ++++++++++++++ .../AsseticExtensionTest.php | 8 ++- .../AsseticBundle/Tests/FunctionalTest.php | 2 +- .../Resources/Resources/views/layout.html.php | 4 ++ .../Tests/Templating/AsseticHelperTest.php | 11 +++- 12 files changed, 169 insertions(+), 87 deletions(-) create mode 100644 src/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php delete mode 100644 src/Symfony/Bundle/AsseticBundle/Templating/FormulaLoader.php create mode 100644 src/Symfony/Bundle/AsseticBundle/Templating/StaticAsseticHelper.php diff --git a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php index 67ba1acf27..47acee3fff 100644 --- a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php +++ b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php @@ -72,9 +72,13 @@ class AsseticExtension extends Extension if ($parameterBag->resolveValue($parameterBag->get('assetic.use_controller'))) { $loader->load('controller.xml'); $container->setParameter('assetic.twig_extension.class', '%assetic.twig_extension.dynamic.class%'); + $container->getDefinition('assetic.helper.dynamic')->addTag('templating.helper', array('alias' => 'assetic')); + $container->remove('assetic.helper.static'); } else { $loader->load('asset_writer.xml'); $container->setParameter('assetic.twig_extension.class', '%assetic.twig_extension.static.class%'); + $container->getDefinition('assetic.helper.static')->addTag('templating.helper', array('alias' => 'assetic')); + $container->remove('assetic.helper.dynamic'); } // register config resources diff --git a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php index 74dbb0fdf7..852b488551 100644 --- a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php +++ b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php @@ -27,7 +27,6 @@ class TemplatingPass implements CompilerPassInterface return; } - $am = $container->getDefinition('assetic.asset_manager'); $engines = $container->getParameterBag()->resolveValue($container->getParameter('templating.engines')); if (!in_array('twig', $engines)) { diff --git a/src/Symfony/Bundle/AsseticBundle/Factory/Loader/AsseticHelperFormulaLoader.php b/src/Symfony/Bundle/AsseticBundle/Factory/Loader/AsseticHelperFormulaLoader.php index 16ff629539..eb164334d8 100644 --- a/src/Symfony/Bundle/AsseticBundle/Factory/Loader/AsseticHelperFormulaLoader.php +++ b/src/Symfony/Bundle/AsseticBundle/Factory/Loader/AsseticHelperFormulaLoader.php @@ -23,18 +23,18 @@ class AsseticHelperFormulaLoader extends BasePhpFormulaLoader protected function registerPrototypes() { return array( - '$view[\'assetic\']->assets(*)' => array(), '$view[\'assetic\']->javascripts(*)' => array('output' => 'js/*.js'), '$view[\'assetic\']->stylesheets(*)' => array('output' => 'css/*.css'), - '$view["assetic"]->assets(*)' => array(), + '$view[\'assetic\']->image(*)' => array('output' => 'images/*', 'single' => true), '$view["assetic"]->javascripts(*)' => array('output' => 'js/*.js'), '$view["assetic"]->stylesheets(*)' => array('output' => 'css/*.css'), - '$view->get(\'assetic\')->assets(*)' => array(), + '$view["assetic"]->image(*)' => array('output' => 'images/*', 'single' => true), '$view->get(\'assetic\')->javascripts(*)' => array('output' => 'js/*.js'), '$view->get(\'assetic\')->stylesheets(*)' => array('output' => 'css/*.css'), - '$view->get("assetic")->assets(*)' => array(), + '$view->get(\'assetic\')->image(*)' => array('output' => 'images/*', 'single' => true), '$view->get("assetic")->javascripts(*)' => array('output' => 'js/*.js'), '$view->get("assetic")->stylesheets(*)' => array('output' => 'css/*.css'), + '$view->get("assetic")->image(*)' => array('output' => 'images/*', 'single' => true), ); } @@ -60,6 +60,12 @@ class Helper global $_call; $_call = func_get_args(); } + + public function image() + { + global $_call; + $_call = func_get_args(); + } } class View extends ArrayObject diff --git a/src/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml b/src/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml index 4ed77052e1..421a91bfdb 100644 --- a/src/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml +++ b/src/Symfony/Bundle/AsseticBundle/Resources/config/templating_php.xml @@ -5,17 +5,26 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Symfony\Bundle\AsseticBundle\Templating\AsseticHelper + Symfony\Bundle\AsseticBundle\Templating\DynamicAsseticHelper + Symfony\Bundle\AsseticBundle\Templating\StaticAsseticHelper Symfony\Bundle\AsseticBundle\Factory\Loader\AsseticHelperFormulaLoader - - + + %assetic.debug% + + + + + + %assetic.debug% + + @@ -23,6 +32,7 @@ %kernel.debug% + diff --git a/src/Symfony/Bundle/AsseticBundle/Templating/AsseticHelper.php b/src/Symfony/Bundle/AsseticBundle/Templating/AsseticHelper.php index b9da7872e5..fb847247b5 100644 --- a/src/Symfony/Bundle/AsseticBundle/Templating/AsseticHelper.php +++ b/src/Symfony/Bundle/AsseticBundle/Templating/AsseticHelper.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\AsseticBundle\Templating; +use Assetic\Asset\AssetInterface; use Assetic\Factory\AssetFactory; use Symfony\Component\Templating\Helper\Helper; @@ -19,42 +20,30 @@ use Symfony\Component\Templating\Helper\Helper; * * @author Kris Wallsmith */ -class AsseticHelper extends Helper +abstract class AsseticHelper extends Helper { protected $factory; protected $debug; - protected $defaultJavascriptsOutput; - protected $defaultStylesheetsOutput; - protected $defaultImageOutput; /** * Constructor. * - * @param AssetFactory $factory The asset factory - * @param Boolean $debug The debug mode - * @param string $defaultJavascriptsOutput The default {@link javascripts()} output string - * @param string $defaultStylesheetsOutput The default {@link stylesheets()} output string - * @param string $defaultImageOutput The default {@link image()} output string + * @param AssetFactory $factory The asset factory + * @param Boolean $debug The debug mode */ - public function __construct(AssetFactory $factory, $debug = false, $defaultJavascriptsOutput = 'js/*.js', $defaultStylesheetsOutput = 'css/*.css', $defaultImageOutput = 'images/*') + public function __construct(AssetFactory $factory, $debug = false) { $this->factory = $factory; $this->debug = $debug; - $this->defaultJavascriptsOutput = $defaultJavascriptsOutput; - $this->defaultStylesheetsOutput = $defaultStylesheetsOutput; - $this->defaultImageOutput = $defaultImageOutput; } /** * Returns an array of javascript urls. - * - * This convenience method wraps {@link assets()} and provides a default - * output string. */ public function javascripts($inputs = array(), $filters = array(), array $options = array()) { if (!isset($options['output'])) { - $options['output'] = $this->defaultJavascriptsOutput; + $options['output'] = 'js/*'; } return $this->getAssetUrls($inputs, $filters, $options); @@ -62,14 +51,11 @@ class AsseticHelper extends Helper /** * Returns an array of stylesheet urls. - * - * This convenience method wraps {@link assets()} and provides a default - * output string. */ public function stylesheets($inputs = array(), $filters = array(), array $options = array()) { if (!isset($options['output'])) { - $options['output'] = $this->defaultStylesheetsOutput; + $options['output'] = 'css/*'; } return $this->getAssetUrls($inputs, $filters, $options); @@ -77,17 +63,16 @@ class AsseticHelper extends Helper /** * Returns an array of one image url. - * - * This convenience method wraps {@link assets()} and provides a default - * output string. */ public function image($inputs = array(), $filters = array(), array $options = array()) { if (!isset($options['output'])) { - $options['output'] = $this->defaultImageOutput; + $options['output'] = 'images/*'; } - return $this->getAssetUrls($inputs, $filters, $options, true); + $options['single'] = true; + + return $this->getAssetUrls($inputs, $filters, $options); } /** @@ -105,11 +90,10 @@ class AsseticHelper extends Helper * @param array|string $inputs An array or comma-separated list of input strings * @param array|string $filters An array or comma-separated list of filter names * @param array $options An array of options - * @param Boolean $single Use only the last input string * * @return array An array of URLs for the asset */ - private function getAssetUrls($inputs = array(), $filters = array(), array $options = array(), $single = false) + private function getAssetUrls($inputs = array(), $filters = array(), array $options = array()) { $explode = function($value) { @@ -128,24 +112,40 @@ class AsseticHelper extends Helper $options['debug'] = $this->debug; } - if ($single && 1 < count($inputs)) { + if (isset($options['single']) && $options['single'] && 1 < count($inputs)) { $inputs = array_slice($inputs, -1); } + if (!isset($options['name'])) { + $options['name'] = $this->factory->generateAssetName($inputs, $filters); + } + $coll = $this->factory->createAsset($inputs, $filters, $options); if (!$options['debug']) { - return array($coll->getTargetUrl()); + return array($this->getAssetUrl($coll, $options)); } $urls = array(); foreach ($coll as $leaf) { - $urls[] = $leaf->getTargetUrl(); + $urls[] = $this->getAssetUrl($leaf, array_replace($options, array( + 'name' => $options['name'].'_'.count($urls), + ))); } return $urls; } + /** + * Returns an URL for the supplied asset. + * + * @param AssetInterface $asset An asset + * @param array $options An array of options + * + * @return string An echo-ready URL + */ + abstract protected function getAssetUrl(AssetInterface $asset, $options = array()); + public function getName() { return 'assetic'; diff --git a/src/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php b/src/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php new file mode 100644 index 0000000000..e1ad188abe --- /dev/null +++ b/src/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php @@ -0,0 +1,45 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Templating; + +use Assetic\Asset\AssetInterface; +use Assetic\Factory\AssetFactory; +use Symfony\Bundle\FrameworkBundle\Templating\Helper\RouterHelper; + +/** + * The dynamic "assetic" templating helper. + * + * @author Kris Wallsmith + */ +class DynamicAsseticHelper extends AsseticHelper +{ + private $routerHelper; + + /** + * Constructor. + * + * @param RouterHelper $routerHelper The router helper + * @param AssetFactory $factory The asset factory + * @param Boolean $debug The debug mode + */ + public function __construct(RouterHelper $routerHelper, AssetFactory $factory, $debug = false) + { + $this->routerHelper = $routerHelper; + + parent::__construct($factory, $debug); + } + + protected function getAssetUrl(AssetInterface $asset, $options = array()) + { + return $this->routerHelper->generate('assetic_'.$options['name']); + } +} diff --git a/src/Symfony/Bundle/AsseticBundle/Templating/FormulaLoader.php b/src/Symfony/Bundle/AsseticBundle/Templating/FormulaLoader.php deleted file mode 100644 index ad2b2d562b..0000000000 --- a/src/Symfony/Bundle/AsseticBundle/Templating/FormulaLoader.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Symfony\Bundle\AsseticBundle\Templating; - -use Assetic\Factory\Loader\FormulaLoaderInterface; -use Assetic\Factory\Resource\ResourceInterface; - -/** - * Loads formulae from PHP templates. - * - * @author Kris Wallsmith - */ -class FormulaLoader implements FormulaLoaderInterface -{ - public function load(ResourceInterface $resource) - { - $tokens = token_get_all($resource->getContent()); - - /** - * @todo Find and extract asset formulae from calls to the following: - * - * * $view['assetic']->assets(...) - * * $view['assetic']->javascripts(...) - * * $view['assetic']->stylesheets(...) - * * $view->get('assetic')->assets(...) - * * $view->get('assetic')->javascripts(...) - * * $view->get('assetic')->stylesheets(...) - * - * The loader will also need to be aware of debug mode and the default - * output strings associated with each method. - */ - - return array(); - } -} diff --git a/src/Symfony/Bundle/AsseticBundle/Templating/StaticAsseticHelper.php b/src/Symfony/Bundle/AsseticBundle/Templating/StaticAsseticHelper.php new file mode 100644 index 0000000000..01928bf190 --- /dev/null +++ b/src/Symfony/Bundle/AsseticBundle/Templating/StaticAsseticHelper.php @@ -0,0 +1,45 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Templating; + +use Assetic\Asset\AssetInterface; +use Assetic\Factory\AssetFactory; +use Symfony\Component\Templating\Helper\AssetsHelper; + +/** + * The static "assetic" templating helper. + * + * @author Kris Wallsmith + */ +class StaticAsseticHelper extends AsseticHelper +{ + private $assetsHelper; + + /** + * Constructor. + * + * @param AssetsHelper $assetsHelper The assets helper + * @param AssetFactory $factory The asset factory + * @param Boolean $debug The debug mode + */ + public function __construct(AssetsHelper $assetsHelper, AssetFactory $factory, $debug = false) + { + $this->assetsHelper = $assetsHelper; + + parent::__construct($factory, $debug); + } + + protected function getAssetUrl(AssetInterface $asset, $options = array()) + { + return $this->assetsHelper->getUrl($asset->getTargetUrl(), isset($options['package']) ? $options['package'] : null); + } +} diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php b/src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php index 6ee53069c1..0b1ce8d934 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php @@ -16,6 +16,7 @@ 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\Definition; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\Scope; use Symfony\Component\Finder\Finder; @@ -53,11 +54,14 @@ class AsseticExtensionTest extends \PHPUnit_Framework_TestCase $this->container = new ContainerBuilder(); $this->container->addScope(new Scope('request')); $this->container->register('request', 'Symfony\\Component\\HttpFoundation\\Request')->setScope('request'); + $this->container->register('templating.helper.assets', $this->getMockClass('Symfony\\Component\\Templating\\Helper\\AssetsHelper')); + $this->container->register('templating.helper.router', $this->getMockClass('Symfony\\Bundle\\FrameworkBundle\\Templating\\Helper\\RouterHelper')) + ->addArgument(new Definition($this->getMockClass('Symfony\\Component\\Routing\\RouterInterface'))); $this->container->register('twig', 'Twig_Environment'); + $this->container->setParameter('kernel.bundles', array()); + $this->container->setParameter('kernel.cache_dir', __DIR__); $this->container->setParameter('kernel.debug', false); $this->container->setParameter('kernel.root_dir', __DIR__); - $this->container->setParameter('kernel.cache_dir', __DIR__); - $this->container->setParameter('kernel.bundles', array()); } /** diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php b/src/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php index 4dd330ca4d..76a6c600a0 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php @@ -106,7 +106,7 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase { // totals include assets defined in both php and twig templates return array( - array(true, 8), + array(true, 6), array(false, 3), ); } diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php b/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php index 5ef05335e9..3044a45c80 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php @@ -11,3 +11,7 @@ stop() ?> + +image('logo.png') as $url): ?> + + diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/Templating/AsseticHelperTest.php b/src/Symfony/Bundle/AsseticBundle/Tests/Templating/AsseticHelperTest.php index 21c9a4cafd..50c82613e8 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/Templating/AsseticHelperTest.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/Templating/AsseticHelperTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\AsseticBundle\Tests\Templating; use Assetic\Asset\AssetCollection; +use Assetic\Asset\AssetInterface; use Assetic\Asset\StringAsset; use Assetic\Factory\AssetFactory; use Symfony\Bundle\AsseticBundle\Templating\AsseticHelper; @@ -30,7 +31,7 @@ class AsseticHelperTest extends \PHPUnit_Framework_TestCase */ public function testUrls($debug, $count, $message) { - $helper = new AsseticHelper(new AssetFactory('/foo', $debug), $debug); + $helper = new AsseticHelperForTest(new AssetFactory('/foo', $debug), $debug); $urls = $helper->javascripts(array('js/jquery.js', 'js/jquery.plugin.js')); $this->assertInternalType('array', $urls, '->javascripts() returns an array'); @@ -45,3 +46,11 @@ class AsseticHelperTest extends \PHPUnit_Framework_TestCase ); } } + +class AsseticHelperForTest extends AsseticHelper +{ + protected function getAssetUrl(AssetInterface $asset, $options = array()) + { + return $asset->getTargetUrl(); + } +}