Merge remote branch 'kriswallsmith/assetic/twig-functions'
* kriswallsmith/assetic/twig-functions: [AsseticBundle] added a listener to add common image request formats when use_controller is on [AsseticBundle] added a node visitor to wrap runtime filter functions with runtime use_controller check [AsseticBundle] added support for Twig functions
This commit is contained in:
commit
fc2c1578ac
@ -71,6 +71,9 @@ class AsseticExtension extends Extension
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// twig functions
|
||||||
|
$container->getDefinition('assetic.twig_extension')->replaceArgument(2, $config['twig']['functions']);
|
||||||
|
|
||||||
// choose dynamic or static
|
// choose dynamic or static
|
||||||
if ($parameterBag->resolveValue($parameterBag->get('assetic.use_controller'))) {
|
if ($parameterBag->resolveValue($parameterBag->get('assetic.use_controller'))) {
|
||||||
$loader->load('controller.xml');
|
$loader->load('controller.xml');
|
||||||
|
@ -91,6 +91,29 @@ class Configuration implements ConfigurationInterface
|
|||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
|
|
||||||
|
// twig
|
||||||
|
->children()
|
||||||
|
->arrayNode('twig')
|
||||||
|
->addDefaultsIfNotSet()
|
||||||
|
->defaultValue(array())
|
||||||
|
->fixXmlConfig('function')
|
||||||
|
->children()
|
||||||
|
->arrayNode('functions')
|
||||||
|
->addDefaultsIfNotSet()
|
||||||
|
->defaultValue(array())
|
||||||
|
->useAttributeAsKey('name')
|
||||||
|
->prototype('variable')
|
||||||
|
->treatNullLike(array())
|
||||||
|
->validate()
|
||||||
|
->ifTrue(function($v) { return !is_array($v); })
|
||||||
|
->thenInvalid('The assetic.twig.functions config %s must be either null or an array.')
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
;
|
;
|
||||||
|
|
||||||
return $builder;
|
return $builder;
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
<?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\Listener;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a few formats to each request.
|
||||||
|
*
|
||||||
|
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
|
||||||
|
*/
|
||||||
|
class RequestListener
|
||||||
|
{
|
||||||
|
public function onCoreRequest(GetResponseEvent $event)
|
||||||
|
{
|
||||||
|
$request = $event->getRequest();
|
||||||
|
|
||||||
|
$request->setFormat('png', 'image/png');
|
||||||
|
$request->setFormat('jpg', 'image/jpeg');
|
||||||
|
$request->setFormat('gif', 'image/gif');
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@
|
|||||||
<parameter key="assetic.routing_loader.class">Symfony\Bundle\AsseticBundle\Routing\AsseticLoader</parameter>
|
<parameter key="assetic.routing_loader.class">Symfony\Bundle\AsseticBundle\Routing\AsseticLoader</parameter>
|
||||||
<parameter key="assetic.cache.class">Assetic\Cache\FilesystemCache</parameter>
|
<parameter key="assetic.cache.class">Assetic\Cache\FilesystemCache</parameter>
|
||||||
<parameter key="assetic.use_controller_worker.class">Symfony\Bundle\AsseticBundle\Factory\Worker\UseControllerWorker</parameter>
|
<parameter key="assetic.use_controller_worker.class">Symfony\Bundle\AsseticBundle\Factory\Worker\UseControllerWorker</parameter>
|
||||||
|
<parameter key="assetic.request_listener.class">Symfony\Bundle\AsseticBundle\Listener\RequestListener</parameter>
|
||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
@ -27,5 +28,8 @@
|
|||||||
<service id="assetic.use_controller_worker" class="%assetic.use_controller_worker.class%" public="false">
|
<service id="assetic.use_controller_worker" class="%assetic.use_controller_worker.class%" public="false">
|
||||||
<tag name="assetic.factory_worker" />
|
<tag name="assetic.factory_worker" />
|
||||||
</service>
|
</service>
|
||||||
|
<service id="assetic.request_listener" class="%assetic.request_listener.class%">
|
||||||
|
<tag name="kernel.listener" event="onCoreRequest" />
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<xsd:sequence>
|
<xsd:sequence>
|
||||||
<xsd:element name="bundle" type="bundle" minOccurs="0" maxOccurs="unbounded" />
|
<xsd:element name="bundle" type="bundle" minOccurs="0" maxOccurs="unbounded" />
|
||||||
<xsd:element name="filter" type="filter" minOccurs="0" maxOccurs="unbounded" />
|
<xsd:element name="filter" type="filter" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
<xsd:element name="twig" type="twig" minOccurs="0" maxOccurs="unbounded" />
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
<xsd:attribute name="debug" type="xsd:string" />
|
<xsd:attribute name="debug" type="xsd:string" />
|
||||||
<xsd:attribute name="use-controller" type="xsd:string" />
|
<xsd:attribute name="use-controller" type="xsd:string" />
|
||||||
@ -32,4 +33,15 @@
|
|||||||
<xsd:attribute name="resource" type="xsd:string" />
|
<xsd:attribute name="resource" type="xsd:string" />
|
||||||
<xsd:anyAttribute namespace="##any" processContents="lax" />
|
<xsd:anyAttribute namespace="##any" processContents="lax" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="twig">
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="function" type="twig_function" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="twig_function">
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
<xsd:anyAttribute namespace="##any" processContents="lax" />
|
||||||
|
</xsd:complexType>
|
||||||
</xsd:schema>
|
</xsd:schema>
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
<tag name="twig.extension" />
|
<tag name="twig.extension" />
|
||||||
<tag name="assetic.templating.twig" />
|
<tag name="assetic.templating.twig" />
|
||||||
<argument type="service" id="assetic.asset_factory" />
|
<argument type="service" id="assetic.asset_factory" />
|
||||||
<argument>%assetic.debug%</argument>
|
|
||||||
<argument>%assetic.use_controller%</argument>
|
<argument>%assetic.use_controller%</argument>
|
||||||
|
<argument type="collection" />
|
||||||
</service>
|
</service>
|
||||||
<service id="assetic.twig_formula_loader" class="%assetic.cached_formula_loader.class%" public="false">
|
<service id="assetic.twig_formula_loader" class="%assetic.cached_formula_loader.class%" public="false">
|
||||||
<tag name="assetic.formula_loader" alias="twig" />
|
<tag name="assetic.formula_loader" alias="twig" />
|
||||||
|
@ -20,3 +20,9 @@ assetic:
|
|||||||
use_controller: true
|
use_controller: true
|
||||||
read_from: "%kernel.root_dir%/web"
|
read_from: "%kernel.root_dir%/web"
|
||||||
bundles: [TestBundle]
|
bundles: [TestBundle]
|
||||||
|
filters:
|
||||||
|
yui_css:
|
||||||
|
jar: %kernel.root_dir/java/yui-compressor-2.4.6.jar
|
||||||
|
twig:
|
||||||
|
functions:
|
||||||
|
yui_css: { output: css/*.css }
|
||||||
|
@ -23,9 +23,9 @@ class AsseticExtension extends BaseAsseticExtension
|
|||||||
{
|
{
|
||||||
private $useController;
|
private $useController;
|
||||||
|
|
||||||
public function __construct(AssetFactory $factory, $debug = false, $useController = false)
|
public function __construct(AssetFactory $factory, $useController = false, $functions = array())
|
||||||
{
|
{
|
||||||
parent::__construct($factory, $debug);
|
parent::__construct($factory, $functions);
|
||||||
|
|
||||||
$this->useController = $useController;
|
$this->useController = $useController;
|
||||||
}
|
}
|
||||||
@ -39,6 +39,11 @@ class AsseticExtension extends BaseAsseticExtension
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getNodeVisitors()
|
||||||
|
{
|
||||||
|
return array(new AsseticNodeVisitor());
|
||||||
|
}
|
||||||
|
|
||||||
public function getGlobals()
|
public function getGlobals()
|
||||||
{
|
{
|
||||||
$globals = parent::getGlobals();
|
$globals = parent::getGlobals();
|
||||||
|
97
src/Symfony/Bundle/AsseticBundle/Twig/AsseticNodeVisitor.php
Normal file
97
src/Symfony/Bundle/AsseticBundle/Twig/AsseticNodeVisitor.php
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<?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\AsseticFilterFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assetic node visitor.
|
||||||
|
*
|
||||||
|
* @author Kris Wallsmith <kris@symfony.com>
|
||||||
|
*/
|
||||||
|
class AsseticNodeVisitor implements \Twig_NodeVisitorInterface
|
||||||
|
{
|
||||||
|
public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
|
||||||
|
{
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env)
|
||||||
|
{
|
||||||
|
if (!$formula = $this->checkNode($node, $env)) {
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
list($input, $filters, $options) = $formula;
|
||||||
|
$line = $node->getLine();
|
||||||
|
|
||||||
|
// check context and call either asset() or path()
|
||||||
|
return new \Twig_Node_Expression_Conditional(
|
||||||
|
new \Twig_Node_Expression_GetAttr(
|
||||||
|
new \Twig_Node_Expression_Name('assetic', $line),
|
||||||
|
new \Twig_Node_Expression_Constant('use_controller', $line),
|
||||||
|
new \Twig_Node(),
|
||||||
|
\Twig_TemplateInterface::ARRAY_CALL,
|
||||||
|
$line
|
||||||
|
),
|
||||||
|
new \Twig_Node_Expression_Function(
|
||||||
|
new \Twig_Node_Expression_Name('path', $line),
|
||||||
|
new \Twig_Node(array(
|
||||||
|
new \Twig_Node_Expression_Constant('_assetic_'.$options['name'], $line),
|
||||||
|
)),
|
||||||
|
$line
|
||||||
|
),
|
||||||
|
new \Twig_Node_Expression_Function(
|
||||||
|
new \Twig_Node_Expression_Name('asset', $line),
|
||||||
|
new \Twig_Node(array($node, new \Twig_Node_Expression_Constant(isset($options['package']) ? $options['package'] : null, $line))),
|
||||||
|
$line
|
||||||
|
),
|
||||||
|
$line
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts formulae from filter function nodes.
|
||||||
|
*
|
||||||
|
* @return array|null The formula
|
||||||
|
*/
|
||||||
|
private function checkNode(\Twig_NodeInterface $node, \Twig_Environment $env)
|
||||||
|
{
|
||||||
|
if ($node instanceof \Twig_Node_Expression_Function) {
|
||||||
|
$name = $node->getNode('name')->getAttribute('name');
|
||||||
|
if ($env->getFunction($name) instanceof AsseticFilterFunction) {
|
||||||
|
$arguments = array();
|
||||||
|
foreach ($node->getNode('arguments') as $argument) {
|
||||||
|
$arguments[] = eval('return '.$env->compile($argument).';');
|
||||||
|
}
|
||||||
|
|
||||||
|
$invoker = $env->getExtension('assetic')->getFilterInvoker($name);
|
||||||
|
$factory = $invoker->getFactory();
|
||||||
|
|
||||||
|
$inputs = isset($arguments[0]) ? (array) $arguments[0] : array();
|
||||||
|
$filters = $invoker->getFilters();
|
||||||
|
$options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array());
|
||||||
|
|
||||||
|
if (!isset($options['name'])) {
|
||||||
|
$options['name'] = $factory->generateAssetName($inputs, $filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($inputs, $filters, $options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriority()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user