Skip to content

Commit

Permalink
[TwigBundle] added the Twig bundle (proof of concept)
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed May 20, 2010
1 parent 2f4c9a3 commit 87143b3
Show file tree
Hide file tree
Showing 13 changed files with 660 additions and 0 deletions.
41 changes: 41 additions & 0 deletions src/Symfony/Framework/TwigBundle/Bundle.php
@@ -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';
}
}
33 changes: 33 additions & 0 deletions src/Symfony/Framework/TwigBundle/Environment.php
@@ -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));
}
}
}
52 changes: 52 additions & 0 deletions src/Symfony/Framework/TwigBundle/Extension/Helpers.php
@@ -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';
}
}
96 changes: 96 additions & 0 deletions src/Symfony/Framework/TwigBundle/Loader/Loader.php
@@ -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);
}
}
87 changes: 87 additions & 0 deletions src/Symfony/Framework/TwigBundle/Node/HelperNode.php
@@ -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 comments on commit 87143b3

Please sign in to comment.