[AsseticBundle] updated twig integration to check debug mode at runtime rather than compile time since twig cannot vary its cache by debug mode
This commit is contained in:
parent
7e33159723
commit
8ad93095d4
@ -36,13 +36,21 @@ class AsseticController
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
public function render($name)
|
||||
public function render($name, $pos = null)
|
||||
{
|
||||
if (!$this->am->has($name)) {
|
||||
throw new NotFoundHttpException('Asset Not Found');
|
||||
throw new NotFoundHttpException(sprintf('The "%s" asset could not be found.', $name));
|
||||
}
|
||||
|
||||
$asset = $this->getAsset($name);
|
||||
if (null !== $pos) {
|
||||
$leaves = array_values(iterator_to_array($asset));
|
||||
if (!isset($leaves[$pos])) {
|
||||
throw new NotFoundHttpException(sprintf('The "%s" asset does not include a leaf at position %d.', $name, $pos));
|
||||
}
|
||||
$asset = $leaves[$pos];
|
||||
}
|
||||
|
||||
$response = $this->createResponse();
|
||||
|
||||
// last-modified
|
||||
|
@ -74,12 +74,10 @@ class AsseticExtension extends Extension
|
||||
// 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%');
|
||||
$container->getDefinition('assetic.helper.dynamic')->addTag('templating.helper', array('alias' => 'assetic'));
|
||||
$container->removeDefinition('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->removeDefinition('assetic.helper.dynamic');
|
||||
}
|
||||
|
@ -5,8 +5,7 @@
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<parameters>
|
||||
<parameter key="assetic.twig_extension.dynamic.class">Symfony\Bundle\AsseticBundle\Twig\DynamicExtension</parameter>
|
||||
<parameter key="assetic.twig_extension.static.class">Symfony\Bundle\AsseticBundle\Twig\StaticExtension</parameter>
|
||||
<parameter key="assetic.twig_extension.class">Symfony\Bundle\AsseticBundle\Twig\AsseticExtension</parameter>
|
||||
<parameter key="assetic.twig_formula_loader.class">Assetic\Extension\Twig\TwigFormulaLoader</parameter>
|
||||
</parameters>
|
||||
|
||||
@ -16,6 +15,7 @@
|
||||
<tag name="assetic.templating.twig" />
|
||||
<argument type="service" id="assetic.asset_factory" />
|
||||
<argument>%assetic.debug%</argument>
|
||||
<argument>%assetic.use_controller%</argument>
|
||||
</service>
|
||||
<service id="assetic.twig_formula_loader" class="%assetic.cached_formula_loader.class%" public="false">
|
||||
<tag name="assetic.formula_loader" alias="twig" />
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\AsseticBundle\Routing;
|
||||
|
||||
use Assetic\Asset\AssetInterface;
|
||||
use Assetic\Factory\LazyAssetManager;
|
||||
use Symfony\Component\Config\Loader\Loader;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
@ -62,22 +63,40 @@ class AsseticLoader extends Loader
|
||||
// routes
|
||||
foreach ($this->am->getNames() as $name) {
|
||||
$asset = $this->am->get($name);
|
||||
$formula = $this->am->getFormula($name);
|
||||
|
||||
$defaults = array(
|
||||
'_controller' => 'assetic.controller:render',
|
||||
'name' => $name,
|
||||
);
|
||||
$this->loadRouteForAsset($routes, $asset, $name);
|
||||
|
||||
if ($extension = pathinfo($asset->getTargetUrl(), PATHINFO_EXTENSION)) {
|
||||
$defaults['_format'] = $extension;
|
||||
// add a route for each "leaf" in debug mode
|
||||
if (isset($formula[2]['debug']) ? $formula[2]['debug'] : $this->am->isDebug()) {
|
||||
$i = 0;
|
||||
foreach ($asset as $leaf) {
|
||||
$pos = $i++;
|
||||
$this->loadRouteForAsset($routes, $leaf, $name.'_'.$pos, $pos);
|
||||
}
|
||||
}
|
||||
|
||||
$routes->add('assetic_'.$name, new Route($asset->getTargetUrl(), $defaults));
|
||||
}
|
||||
|
||||
return $routes;
|
||||
}
|
||||
|
||||
private function loadRouteForAsset(RouteCollection $routes, AssetInterface $asset, $name, $pos = null)
|
||||
{
|
||||
$defaults = array(
|
||||
'_controller' => 'assetic.controller:render',
|
||||
'name' => $name,
|
||||
'pos' => $pos,
|
||||
);
|
||||
|
||||
$pattern = $asset->getTargetUrl();
|
||||
|
||||
if ($format = pathinfo($pattern, PATHINFO_EXTENSION)) {
|
||||
$defaults['_format'] = $format;
|
||||
}
|
||||
|
||||
$routes->add('_assetic_'.$name, new Route($pattern, $defaults));
|
||||
}
|
||||
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return 'assetic' == $type;
|
||||
|
@ -40,6 +40,6 @@ class DynamicAsseticHelper extends AsseticHelper
|
||||
|
||||
protected function getAssetUrl(AssetInterface $asset, $options = array())
|
||||
{
|
||||
return $this->routerHelper->generate('assetic_'.$options['name']);
|
||||
return $this->routerHelper->generate('_assetic_'.$options['name']);
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDebugAndAssetCount
|
||||
* @dataProvider provideAmDebugAndAssetCount
|
||||
*/
|
||||
public function testKernel($debug, $count)
|
||||
{
|
||||
@ -55,7 +55,7 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDebugAndAssetCount
|
||||
* @dataProvider provideRouterDebugAndAssetCount
|
||||
*/
|
||||
public function testRoutes($debug, $count)
|
||||
{
|
||||
@ -64,7 +64,7 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$matches = 0;
|
||||
foreach (array_keys($kernel->getContainer()->get('router')->getRouteCollection()->all()) as $name) {
|
||||
if (0 === strpos($name, 'assetic_')) {
|
||||
if (0 === strpos($name, '_assetic_')) {
|
||||
++$matches;
|
||||
}
|
||||
}
|
||||
@ -102,11 +102,18 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(2, count($crawler->filter('script[src$=".js"]')));
|
||||
}
|
||||
|
||||
public function provideDebugAndAssetCount()
|
||||
public function provideAmDebugAndAssetCount()
|
||||
{
|
||||
// totals include assets defined in both php and twig templates
|
||||
return array(
|
||||
array(true, 6),
|
||||
array(true, 3),
|
||||
array(false, 3),
|
||||
);
|
||||
}
|
||||
|
||||
public function provideRouterDebugAndAssetCount()
|
||||
{
|
||||
return array(
|
||||
array(true, 9),
|
||||
array(false, 3),
|
||||
);
|
||||
}
|
||||
|
49
src/Symfony/Bundle/AsseticBundle/Twig/AsseticExtension.php
Normal file
49
src/Symfony/Bundle/AsseticBundle/Twig/AsseticExtension.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?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\Twig;
|
||||
|
||||
use Assetic\Extension\Twig\AsseticExtension as BaseAsseticExtension;
|
||||
use Assetic\Factory\AssetFactory;
|
||||
|
||||
/**
|
||||
* Assetic extension.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
class AsseticExtension extends BaseAsseticExtension
|
||||
{
|
||||
private $useController;
|
||||
|
||||
public function __construct(AssetFactory $factory, $debug = false, $useController = false)
|
||||
{
|
||||
parent::__construct($factory, $debug);
|
||||
|
||||
$this->useController = $useController;
|
||||
}
|
||||
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return array(
|
||||
new AsseticTokenParser($this->factory, 'javascripts', 'js/*.js', false, array('package')),
|
||||
new AsseticTokenParser($this->factory, 'stylesheets', 'css/*.css', false, array('package')),
|
||||
new AsseticTokenParser($this->factory, 'image', 'images/*', true, array('package')),
|
||||
);
|
||||
}
|
||||
|
||||
public function getGlobals()
|
||||
{
|
||||
$globals = parent::getGlobals();
|
||||
$globals['assetic']['use_controller'] = $this->useController;
|
||||
|
||||
return $globals;
|
||||
}
|
||||
}
|
57
src/Symfony/Bundle/AsseticBundle/Twig/AsseticNode.php
Normal file
57
src/Symfony/Bundle/AsseticBundle/Twig/AsseticNode.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?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\Twig;
|
||||
|
||||
use Assetic\Asset\AssetInterface;
|
||||
use Assetic\Extension\Twig\AsseticNode as BaseAsseticNode;
|
||||
|
||||
/**
|
||||
* Assetic node.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
class AsseticNode extends BaseAsseticNode
|
||||
{
|
||||
protected function compileAssetUrl(\Twig_Compiler $compiler, AssetInterface $asset, $name)
|
||||
{
|
||||
$compiler
|
||||
->raw('isset($context[\'assetic\'][\'use_controller\']) && $context[\'assetic\'][\'use_controller\'] ? ')
|
||||
->subcompile($this->getPathFunction($name))
|
||||
->raw(' : ')
|
||||
->subcompile($this->getAssetFunction($asset->getTargetUrl()))
|
||||
;
|
||||
}
|
||||
|
||||
private function getPathFunction($name)
|
||||
{
|
||||
return new \Twig_Node_Expression_Function(
|
||||
new \Twig_Node_Expression_Name('path', $this->getLine()),
|
||||
new \Twig_Node(array(new \Twig_Node_Expression_Constant('_assetic_'.$name, $this->getLine()))),
|
||||
$this->getLine()
|
||||
);
|
||||
}
|
||||
|
||||
private function getAssetFunction($path)
|
||||
{
|
||||
$arguments = array(new \Twig_Node_Expression_Constant($path, $this->getLine()));
|
||||
|
||||
if ($this->hasAttribute('package')) {
|
||||
$arguments[] = new \Twig_Node_Expression_Constant($this->getAttribute('package'), $this->getLine());
|
||||
}
|
||||
|
||||
return new \Twig_Node_Expression_Function(
|
||||
new \Twig_Node_Expression_Name('asset', $this->getLine()),
|
||||
new \Twig_Node($arguments),
|
||||
$this->getLine()
|
||||
);
|
||||
}
|
||||
}
|
28
src/Symfony/Bundle/AsseticBundle/Twig/AsseticTokenParser.php
Normal file
28
src/Symfony/Bundle/AsseticBundle/Twig/AsseticTokenParser.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?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\Twig;
|
||||
|
||||
use Assetic\Asset\AssetInterface;
|
||||
use Assetic\Extension\Twig\AsseticTokenParser as BaseAsseticTokenParser;
|
||||
|
||||
/**
|
||||
* Assetic token parser.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
class AsseticTokenParser extends BaseAsseticTokenParser
|
||||
{
|
||||
protected function createNode(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null)
|
||||
{
|
||||
return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<?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\Twig;
|
||||
|
||||
use Assetic\Extension\Twig\AsseticExtension;
|
||||
use Assetic\Factory\AssetFactory;
|
||||
|
||||
/**
|
||||
* The dynamic extension is used when use_controllers is enabled.
|
||||
*
|
||||
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
|
||||
*/
|
||||
class DynamicExtension extends AsseticExtension
|
||||
{
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return array(
|
||||
new DynamicTokenParser($this->factory, 'javascripts', 'js/*.js', $this->debug, false, array('package')),
|
||||
new DynamicTokenParser($this->factory, 'stylesheets', 'css/*.css', $this->debug, false, array('package')),
|
||||
new DynamicTokenParser($this->factory, 'image', 'images/*', $this->debug, true, array('package')),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?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\Twig;
|
||||
|
||||
use Assetic\Extension\Twig\AsseticNode;
|
||||
|
||||
/**
|
||||
* The "dynamic" node uses a controller to render assets.
|
||||
*
|
||||
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
|
||||
*/
|
||||
class DynamicNode extends AsseticNode
|
||||
{
|
||||
/**
|
||||
* Renders the asset URL using Symfony's path() function.
|
||||
*/
|
||||
protected function getAssetUrlNode(\Twig_NodeInterface $body)
|
||||
{
|
||||
return new \Twig_Node_Expression_Function(
|
||||
new \Twig_Node_Expression_Name('path', $body->getLine()),
|
||||
new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Constant('assetic_'.$this->getAttribute('name'), $body->getLine()),
|
||||
)),
|
||||
$body->getLine()
|
||||
);
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?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\Twig;
|
||||
|
||||
use Assetic\Extension\Twig\AsseticTokenParser;
|
||||
|
||||
/**
|
||||
* Parses an Assetic tag.
|
||||
*
|
||||
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
|
||||
*/
|
||||
class DynamicTokenParser extends AsseticTokenParser
|
||||
{
|
||||
static protected function createNode(\Twig_NodeInterface $body, array $inputs, array $filters, array $attributes, $lineno = 0, $tag = null)
|
||||
{
|
||||
return new DynamicNode($body, $inputs, $filters, $attributes, $lineno, $tag);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<?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\Twig;
|
||||
|
||||
use Assetic\Extension\Twig\AsseticExtension;
|
||||
use Assetic\Factory\AssetFactory;
|
||||
|
||||
/**
|
||||
* The static extension is used when use_controllers is disabled.
|
||||
*
|
||||
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
|
||||
*/
|
||||
class StaticExtension extends AsseticExtension
|
||||
{
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return array(
|
||||
new StaticTokenParser($this->factory, 'javascripts', 'js/*.js', $this->debug, false, array('package')),
|
||||
new StaticTokenParser($this->factory, 'stylesheets', 'css/*.css', $this->debug, false, array('package')),
|
||||
new StaticTokenParser($this->factory, 'image', 'images/*', $this->debug, true, array('package')),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
<?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\Twig;
|
||||
|
||||
use Assetic\Extension\Twig\AsseticNode;
|
||||
|
||||
/**
|
||||
* The "static" node references a file in the web directory.
|
||||
*
|
||||
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
|
||||
*/
|
||||
class StaticNode extends AsseticNode
|
||||
{
|
||||
/**
|
||||
* Renders the asset URL using Symfony's asset() function.
|
||||
*/
|
||||
protected function getAssetUrlNode(\Twig_NodeInterface $body)
|
||||
{
|
||||
return new \Twig_Node_Expression_Function(
|
||||
new \Twig_Node_Expression_Name('asset', $body->getLine()),
|
||||
new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Constant($this->getAttribute('output'), $body->getLine()),
|
||||
new \Twig_Node_Expression_Constant($this->hasAttribute('package') ? $this->getAttribute('package') : null, $body->getLine()),
|
||||
)),
|
||||
$body->getLine()
|
||||
);
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?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\Twig;
|
||||
|
||||
use Assetic\Extension\Twig\AsseticTokenParser;
|
||||
|
||||
/**
|
||||
* Parses an Assetic tag.
|
||||
*
|
||||
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
|
||||
*/
|
||||
class StaticTokenParser extends AsseticTokenParser
|
||||
{
|
||||
static protected function createNode(\Twig_NodeInterface $body, array $inputs, array $filters, array $attributes, $lineno = 0, $tag = null)
|
||||
{
|
||||
return new StaticNode($body, $inputs, $filters, $attributes, $lineno, $tag);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user