[TwigBundle] added the Twig bundle (proof of concept)
This commit is contained in:
parent
2f4c9a32e9
commit
87143b3dd3
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle;
|
||||
|
||||
use Symfony\Foundation\Bundle\Bundle as BaseBundle;
|
||||
use Symfony\Components\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Components\DependencyInjection\Loader\Loader;
|
||||
use Symfony\Components\DependencyInjection\Loader\XmlFileLoader;
|
||||
use Symfony\Components\DependencyInjection\BuilderConfiguration;
|
||||
use Symfony\Framework\TwigBundle\DependencyInjection\TwigExtension;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bundle.
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class Bundle extends BaseBundle
|
||||
{
|
||||
/**
|
||||
* Customizes the Container instance.
|
||||
*
|
||||
* @param Symfony\Components\DependencyInjection\ContainerInterface $container A ContainerInterface instance
|
||||
*
|
||||
* @return Symfony\Components\DependencyInjection\BuilderConfiguration A BuilderConfiguration instance
|
||||
*/
|
||||
public function buildContainer(ContainerInterface $container)
|
||||
{
|
||||
Loader::registerExtension(new TwigExtension());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle\DependencyInjection;
|
||||
|
||||
use Symfony\Components\DependencyInjection\Loader\LoaderExtension;
|
||||
use Symfony\Components\DependencyInjection\Loader\XmlFileLoader;
|
||||
use Symfony\Components\DependencyInjection\BuilderConfiguration;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* TwigExtension.
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class TwigExtension extends LoaderExtension
|
||||
{
|
||||
public function configLoad($config)
|
||||
{
|
||||
$configuration = new BuilderConfiguration();
|
||||
|
||||
$loader = new XmlFileLoader(__DIR__.'/../Resources/config');
|
||||
$configuration->merge($loader->load('twig.xml'));
|
||||
|
||||
$configuration->setParameter('twig_options', array_replace($configuration->getParameter('twig_options'), $config));
|
||||
|
||||
return $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base path for the XSD files.
|
||||
*
|
||||
* @return string The XSD base path
|
||||
*/
|
||||
public function getXsdValidationBasePath()
|
||||
{
|
||||
return __DIR__.'/../Resources/config/';
|
||||
}
|
||||
|
||||
public function getNamespace()
|
||||
{
|
||||
return 'http://www.symfony-project.org/schema/dic/twig';
|
||||
}
|
||||
|
||||
public function getAlias()
|
||||
{
|
||||
return 'twig';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle;
|
||||
|
||||
use Symfony\Components\DependencyInjection\ContainerInterface;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* TwigExtension.
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class Environment extends \Twig_Environment
|
||||
{
|
||||
public function __construct(ContainerInterface $container, \Twig_LoaderInterface $loader = null, $options = array())
|
||||
{
|
||||
parent::__construct($loader, $options);
|
||||
|
||||
foreach ($container->findAnnotatedServiceIds('twig.extension') as $id => $attributes) {
|
||||
$this->addExtension($container->getService($id));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle\Extension;
|
||||
|
||||
use Symfony\Components\Templating\Engine;
|
||||
use Symfony\Framework\TwigBundle\TokenParser\StylesheetTokenParser;
|
||||
use Symfony\Framework\TwigBundle\TokenParser\StylesheetsTokenParser;
|
||||
use Symfony\Framework\TwigBundle\TokenParser\RouteTokenParser;
|
||||
use Symfony\Framework\TwigBundle\TokenParser\RenderTokenParser;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class Helpers extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Returns the token parser instance to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_TokenParser instances
|
||||
*/
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return array(
|
||||
new StylesheetTokenParser(),
|
||||
new StylesheetsTokenParser(),
|
||||
new RouteTokenParser(),
|
||||
new RenderTokenParser(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
* @return string The extension name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'symfony.helpers';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle\Loader;
|
||||
|
||||
use Symfony\Components\Templating\Engine;
|
||||
use Symfony\Components\Templating\Storage\Storage;
|
||||
use Symfony\Components\Templating\Storage\FileStorage;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class Loader implements \Twig_LoaderInterface
|
||||
{
|
||||
protected $engine;
|
||||
|
||||
public function setEngine(Engine $engine)
|
||||
{
|
||||
$this->engine = $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code of a template, given its name.
|
||||
*
|
||||
* @param string $name string The name of the template to load
|
||||
*
|
||||
* @return string The template source code
|
||||
*/
|
||||
public function getSource($name)
|
||||
{
|
||||
if ($name instanceof Storage) {
|
||||
return $name->getContent();
|
||||
}
|
||||
|
||||
list($name, $options) = $this->engine->splitTemplateName($name);
|
||||
|
||||
$template = $this->engine->getLoader()->load($name, $options);
|
||||
|
||||
if (false === $template) {
|
||||
throw new \InvalidArgumentException(sprintf('The template "%s" does not exist (renderer: %s).', $name, $options['renderer']));
|
||||
}
|
||||
|
||||
return $template->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache key to use for the cache for a given template name.
|
||||
*
|
||||
* @param string $name string The name of the template to load
|
||||
*
|
||||
* @return string The cache key
|
||||
*/
|
||||
public function getCacheKey($name)
|
||||
{
|
||||
if ($name instanceof Storage) {
|
||||
return (string) $name;
|
||||
}
|
||||
|
||||
list($name, $options) = $this->engine->splitTemplateName($name);
|
||||
|
||||
return $name.'_'.serialize($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the template is still fresh.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*/
|
||||
public function isFresh($name, $time)
|
||||
{
|
||||
if ($name instanceof Storage) {
|
||||
if ($name instanceof FileStorage)
|
||||
{
|
||||
return filemtime((string) $name) < $time;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
list($name, $options) = $this->engine->splitTemplateName($name);
|
||||
|
||||
return $this->engine->getLoader()->isFresh($name, $options, $time);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle\Node;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class HelperNode extends \Twig_Node implements \Twig_NodeListInterface
|
||||
{
|
||||
protected $name;
|
||||
protected $method;
|
||||
protected $arguments;
|
||||
protected $echo;
|
||||
|
||||
public function __construct($name, $method, \Twig_NodeList $arguments, $echo, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct($lineno, $tag);
|
||||
$this->name = $name;
|
||||
$this->method = $method;
|
||||
$this->arguments = $arguments;
|
||||
$this->echo = $echo;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return get_class($this).'('.$this->arguments.')';
|
||||
}
|
||||
|
||||
public function getNodes()
|
||||
{
|
||||
return array($this->arguments);
|
||||
}
|
||||
|
||||
public function setNodes(array $nodes)
|
||||
{
|
||||
$this->arguments = $nodes[0];
|
||||
}
|
||||
|
||||
public function compile($compiler)
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
if ($this->echo) {
|
||||
$compiler->raw('echo ');
|
||||
}
|
||||
|
||||
$compiler->write('$context[\'_view\']->'.$this->name.'->'.$this->method.'(');
|
||||
|
||||
$count = count($this->arguments->getNodes());
|
||||
foreach ($this->arguments->getNodes() as $i => $node) {
|
||||
$compiler->subcompile($node);
|
||||
|
||||
if ($i !== $count - 1) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
}
|
||||
|
||||
$compiler->raw(");\n");
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle\Renderer;
|
||||
|
||||
use Symfony\Components\Templating\Renderer\Renderer as BaseRenderer;
|
||||
use Symfony\Components\Templating\Storage\Storage;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class Renderer extends BaseRenderer
|
||||
{
|
||||
protected $environment;
|
||||
|
||||
public function __construct(\Twig_Environment $environment)
|
||||
{
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a template.
|
||||
*
|
||||
* @param Storage $template The template to render
|
||||
* @param array $parameters An array of parameters to pass to the template
|
||||
*
|
||||
* @return string|false The evaluated template, or false if the renderer is unable to render the template
|
||||
*/
|
||||
public function evaluate(Storage $template, array $parameters = array())
|
||||
{
|
||||
$parameters['_view'] = $this->engine;
|
||||
|
||||
return $this->environment->loadTemplate($template)->render($parameters);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<xsd:schema xmlns="http://www.symfony-project.org/schema/dic/twig"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://www.symfony-project.org/schema/dic/twig"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<xsd:element name="config" type="config" />
|
||||
|
||||
<xsd:complexType name="config">
|
||||
<xsd:attribute name="charset" type="xsd:string" />
|
||||
<xsd:attribute name="debug" type="xsd:string" />
|
||||
<xsd:attribute name="cache" type="xsd:string" />
|
||||
<xsd:attribute name="trim_blocks" type="xsd:string" />
|
||||
<xsd:attribute name="auto_reload" type="xsd:string" />
|
||||
<xsd:attribute name="base_template_class" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" ?>
|
||||
|
||||
<container xmlns="http://www.symfony-project.org/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<parameters>
|
||||
<parameter key="twig.class">Symfony\Framework\TwigBundle\Environment</parameter>
|
||||
<parameter key="twig_options" type="collection">
|
||||
<parameter key="charset">%kernel.charset%</parameter>
|
||||
<parameter key="debug">%kernel.debug%</parameter>
|
||||
<parameter key="cache">%kernel.cache_dir%/twig</parameter>
|
||||
</parameter>
|
||||
<parameter key="twig_loader.class">Symfony\Framework\TwigBundle\Loader\Loader</parameter>
|
||||
<parameter key="twig_renderer.class">Symfony\Framework\TwigBundle\Renderer\Renderer</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
<service id="twig" class="%twig.class%">
|
||||
<argument type="service" id="service_container" />
|
||||
<argument type="service" id="twig_loader" />
|
||||
<argument>%twig_options%</argument>
|
||||
</service>
|
||||
|
||||
<service id="twig_loader" class="%twig_loader.class%">
|
||||
<call method="setEngine">
|
||||
<argument type="service" id="templating" />
|
||||
</call>
|
||||
</service>
|
||||
|
||||
<service id="twig_renderer" class="%twig_renderer.class%">
|
||||
<annotation name="templating.renderer" alias="twig" />
|
||||
<argument type="service" id="twig" />
|
||||
</service>
|
||||
|
||||
<service id="twig_extension_escaper" class="\Twig_Extension_Escaper">
|
||||
<annotation name="twig.extension" />
|
||||
</service>
|
||||
|
||||
<service id="twig_extension_helpers" class="Symfony\Framework\TwigBundle\Extension\Helpers">
|
||||
<annotation name="twig.extension" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle\TokenParser;
|
||||
|
||||
use Symfony\Framework\TwigBundle\Node\HelperNode;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper for the actions helper render() method.
|
||||
*
|
||||
* {% render 'BlogBundle:Post:list' with ['path': ['limit': 2], 'standalone': false, 'alt': 'BlogBundle:Post:error'] %}
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class RenderTokenParser extends \Twig_TokenParser
|
||||
{
|
||||
public function parse(\Twig_Token $token)
|
||||
{
|
||||
$nodes = array();
|
||||
|
||||
$lineno = $token->getLine();
|
||||
$nodes[] = $this->parser->getExpressionParser()->parseExpression();
|
||||
|
||||
if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'with'))
|
||||
{
|
||||
$this->parser->getStream()->expect(\Twig_Token::NAME_TYPE, 'with');
|
||||
$nodes[] = $this->parser->getExpressionParser()->parseExpression();
|
||||
}
|
||||
|
||||
$this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
|
||||
|
||||
return new HelperNode('actions', 'render', new \Twig_NodeList($nodes), true, $lineno, $this->getTag());
|
||||
}
|
||||
|
||||
public function getTag()
|
||||
{
|
||||
return 'render';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle\TokenParser;
|
||||
|
||||
use Symfony\Framework\TwigBundle\Node\HelperNode;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper for the route helper generate() method.
|
||||
*
|
||||
* {% route blog_post with ['id': post.id] %}
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class RouteTokenParser extends \Twig_TokenParser
|
||||
{
|
||||
public function parse(\Twig_Token $token)
|
||||
{
|
||||
$nodes = array();
|
||||
|
||||
$lineno = $token->getLine();
|
||||
$nodes[] = $this->parser->getExpressionParser()->parseExpression();
|
||||
|
||||
if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'with'))
|
||||
{
|
||||
$this->parser->getStream()->expect(\Twig_Token::NAME_TYPE, 'with');
|
||||
$nodes[] = $this->parser->getExpressionParser()->parseExpression();
|
||||
}
|
||||
|
||||
$this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
|
||||
|
||||
return new HelperNode('router', 'generate', new \Twig_NodeList($nodes), true, $lineno, $this->getTag());
|
||||
}
|
||||
|
||||
public function getTag()
|
||||
{
|
||||
return 'route';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle\TokenParser;
|
||||
|
||||
use Symfony\Framework\TwigBundle\Node\HelperNode;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper for the stylesheets helper add() method.
|
||||
*
|
||||
* {% stylesheet 'bundles/blog/css/blog.css' with ['media': 'screen'] %}
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class StylesheetTokenParser extends \Twig_TokenParser
|
||||
{
|
||||
public function parse(\Twig_Token $token)
|
||||
{
|
||||
$nodes = array();
|
||||
|
||||
$lineno = $token->getLine();
|
||||
$nodes[] = $this->parser->getExpressionParser()->parseExpression();
|
||||
|
||||
if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'with'))
|
||||
{
|
||||
$this->parser->getStream()->expect(\Twig_Token::NAME_TYPE, 'with');
|
||||
$nodes[] = $this->parser->getExpressionParser()->parseExpression();
|
||||
}
|
||||
|
||||
$this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
|
||||
|
||||
return new HelperNode('stylesheets', 'add', new \Twig_NodeList($nodes), false, $lineno, $this->getTag());
|
||||
}
|
||||
|
||||
public function getTag()
|
||||
{
|
||||
return 'stylesheet';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Framework\TwigBundle\TokenParser;
|
||||
|
||||
use Symfony\Framework\TwigBundle\Node\HelperNode;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper for the stylesheets helper output() method.
|
||||
*
|
||||
* {% stylesheets %}
|
||||
*
|
||||
* @package Symfony
|
||||
* @subpackage Framework_TwigBundle
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class StylesheetsTokenParser extends \Twig_TokenParser
|
||||
{
|
||||
public function parse(\Twig_Token $token)
|
||||
{
|
||||
$this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
|
||||
|
||||
return new HelperNode('stylesheets', 'render', new \Twig_NodeList(array()), true, $token->getLine(), $this->getTag());
|
||||
}
|
||||
|
||||
public function getTag()
|
||||
{
|
||||
return 'stylesheets';
|
||||
}
|
||||
}
|
Reference in New Issue