* the odd and even filters are now tests:
{{ foo|odd }} must now be written {{ foo is odd }}
+ * added a way to implement custom logic for resolving token parsers given a tag name
* fixed js escaper to be stricter (now uses a whilelist-based js escaper)
* added a "constant" filter
* added a "constant" test
$this->getTokenParsers();
}
- $this->parsers[] = $parser;
+ $this->parsers->addTokenParser($parser);
}
public function getTokenParsers()
{
if (null === $this->parsers) {
- $this->parsers = array();
+ $this->parsers = new Twig_TokenParserBroker;
foreach ($this->getExtensions() as $extension) {
- $this->parsers = array_merge($this->parsers, $extension->getTokenParsers());
+ $parsers = $extension->getTokenParsers();
+ foreach($parsers as $parser) {
+ if ($parser instanceof Twig_TokenParserInterface) {
+ $this->parsers->addTokenParser($parser);
+ } else if ($parser instanceof Twig_TokenParserBrokerInterface) {
+ $this->parsers->addTokenParserBroker($parser);
+ } else {
+ throw new InvalidArgumentException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances');
+ }
+ }
}
}
/**
* Returns the token parser instances to add to the existing list.
*
- * @return array An array of Twig_TokenParser instances
+ * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
public function getTokenParsers()
{
}
/**
- * Returns the token parser instance to add to the existing list.
+ * Returns the token parser instances to add to the existing list.
*
- * @return array An array of Twig_TokenParser instances
+ * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
public function getTokenParsers()
{
class Twig_Extension_I18n extends Twig_Extension
{
/**
- * Returns the token parser instance to add to the existing list.
+ * Returns the token parser instances to add to the existing list.
*
- * @return array An array of Twig_TokenParser instances
+ * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
public function getTokenParsers()
{
}
/**
- * Returns the token parser instance to add to the existing list.
+ * Returns the token parser instances to add to the existing list.
*
- * @return array An array of Twig_TokenParser instances
+ * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
public function getTokenParsers()
{
/**
* Returns the token parser instances to add to the existing list.
*
- * @return array An array of Twig_TokenParser instances
+ * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
public function getTokenParsers();
public function parse(Twig_TokenStream $stream)
{
// tag handlers
- $this->handlers = array();
- foreach ($this->env->getTokenParsers() as $handler) {
- $handler->setParser($this);
-
- $this->handlers[$handler->getTag()] = $handler;
- }
+ $this->handlers = $this->env->getTokenParsers();
+ $this->handlers->setParser($this);
// node visitors
$this->visitors = $this->env->getNodeVisitors();
return new Twig_Node($rv, array(), $lineno);
}
- if (!isset($this->handlers[$token->getValue()])) {
+ $subparser = $this->handlers->getTokenParser($token->getValue());
+ if (null === $subparser) {
throw new Twig_SyntaxError(sprintf('Unknown tag name "%s"', $token->getValue()), $token->getLine());
}
$this->stream->next();
- $subparser = $this->handlers[$token->getValue()];
$node = $subparser->parse($token);
if (!is_null($node)) {
$rv[] = $node;
--- /dev/null
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ * (c) 2010 Arnaud Le Blanc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Default implementation of a token parser broker.
+ *
+ * @package twig
+ * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ * @version SVN: $Id$
+ */
+class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
+{
+ protected $parser;
+ protected $parsers = array();
+ protected $brokers = array();
+
+ /**
+ * Constructor
+ *
+ * @param array|Iterable $parsers An Iterable of Twig_TokenParserInterface instances
+ * @param array|Iterable $brokers An Iterable of Twig_TokenParserBrokerInterface instances
+ */
+ public function __construct($parsers = array(), $brokers = array())
+ {
+ foreach($parsers as $parser) {
+ if (!$parser instanceof Twig_TokenParserInterface) {
+ throw new InvalidArgumentException(
+ '$parsers must a an array of Twig_TokenParserInterface');
+ }
+ $this->parsers[$parser->getTag()] = $parser;
+ }
+ foreach($brokers as $broker) {
+ if (!$broker instanceof Twig_TokenParserBrokerInterface) {
+ throw new InvalidArgumentException(
+ '$brokers must a an array of Twig_TokenParserBrokerInterface');
+ }
+ $this->brokers[] = $broker;
+ }
+ }
+
+ /**
+ * Adds a TokenParser
+ *
+ * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance
+ */
+ public function addTokenParser(Twig_TokenParserInterface $parser)
+ {
+ $this->parsers[$parser->getTag()] = $parser;
+ }
+
+ /**
+ * Adds a TokenParserBroker
+ *
+ * @param Twig_TokenParserBroker $broker A Twig_TokenParserBroker instance
+ */
+ public function addTokenParserBroker(Twig_TokenParserBroker $broker)
+ {
+ $this->brokers[] = $broker;
+ }
+
+ /**
+ * Get a suitable TokenParser for $tag
+ *
+ * First looks in parsers, then in brokers.
+ *
+ * @param string $tag A tag name
+ * @return null|Twig_TokenParserInterface A Twig_TokenParserInterface or null if no suitable TokenParser was found
+ */
+ public function getTokenParser($tag)
+ {
+ if (isset($this->parsers[$tag])) {
+ return $this->parsers[$tag];
+ }
+ $broker = end($this->brokers);
+ while (false !== $broker) {
+ $parser = $broker->getTokenParser($tag);
+ if (null !== $parser) {
+ return $parser;
+ }
+ $broker = prev($this->brokers);
+ }
+ return null;
+ }
+
+ public function getParser()
+ {
+ return $this->parser;
+ }
+
+ public function setParser(Twig_ParserInterface $parser)
+ {
+ $this->parser = $parser;
+ foreach($this->parsers as $tokenParser) {
+ $tokenParser->setParser($parser);
+ }
+ foreach($this->brokers as $broker) {
+ $broker->setParser($parser);
+ }
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ * (c) 2010 Arnaud Le Blanc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface implemented by token parser brokers.
+ *
+ * Token parser brokers allows to implement custom logic in the process of resolving a token parser for a given tag name.
+ *
+ * @package twig
+ * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ * @version SVN: $Id$
+ */
+interface Twig_TokenParserBrokerInterface
+{
+ /**
+ * Get a TokenParser suitable for $tag
+ *
+ * @param string $tag A tag name
+ * @return null|Twig_TokenParserInterface A Twig_TokenParserInterface or null if no suitable TokenParser was found
+ */
+ function getTokenParser($tag);
+
+ /**
+ * Calls Twig_TokenParserInterface::setParser on all parsers the implementation knowns of
+ *
+ * @param Twig_ParserInterface $parser A Twig_ParserInterface interface
+ */
+ function setParser(Twig_ParserInterface $parser);
+
+ /**
+ * Get the Twig_ParserInterface
+ *
+ * @return null|Twig_ParserInterface A Twig_ParserInterface instance of null
+ */
+ function getParser();
+}