[TwigBundle] made trans and transchoice tags more flexible

Both tags accept variables now:

    {% trans label %}

    {% transchoice %}
      {{ error }}
    {% endtranschoice %}

Optionally, the with keywords allows to pass the placeholder values:

    {% trans label with vars %}
This commit is contained in:
Fabien Potencier 2010-09-30 19:13:01 +02:00
parent 4297609156
commit eff1bdf50f
3 changed files with 59 additions and 32 deletions

View File

@ -18,9 +18,9 @@ namespace Symfony\Bundle\TwigBundle\Node;
*/
class TransNode extends \Twig_Node
{
public function __construct(\Twig_NodeInterface $body, \Twig_NodeInterface $domain, \Twig_Node_Expression $count = null, $lineno, $tag = null)
public function __construct(\Twig_NodeInterface $body, \Twig_NodeInterface $domain, \Twig_Node_Expression $count = null, \Twig_Node_Expression $vars = null, $lineno, $tag = null)
{
parent::__construct(array('count' => $count, 'body' => $body, 'domain' => $domain), array(), $lineno, $tag);
parent::__construct(array('count' => $count, 'body' => $body, 'domain' => $domain, 'vars' => $vars), array(), $lineno, $tag);
}
/**
@ -32,7 +32,12 @@ class TransNode extends \Twig_Node
{
$compiler->addDebugInfo($this);
list($msg, $vars) = $this->compileString($this->body);
if ($this->isSimpleString($this->body)) {
list($msg, $vars) = $this->compileString($this->body);
} else {
$msg = $this->body;
$vars = $this->vars;
}
$method = null === $this->count ? 'trans' : 'transChoice';
@ -52,13 +57,19 @@ class TransNode extends \Twig_Node
$compiler->raw('array(');
foreach ($vars as $var) {
$compiler
->string('{{ '.$var['name'].' }}')
->raw(' => ')
->subcompile($var)
->raw(', ')
;
if (is_array($vars)) {
foreach ($vars as $var) {
$compiler
->string('{{ '.$var['name'].' }}')
->raw(' => ')
->subcompile($var)
->raw(', ')
;
}
} elseif (null !== $vars) {
$compiler->subcompile($vars);
} else {
$compiler->raw('array()');
}
$compiler
@ -91,4 +102,21 @@ class TransNode extends \Twig_Node
return array(new \Twig_Node(array(new \Twig_Node_Expression_Constant(trim($msg), $node->getLine()))), $vars);
}
protected function isSimpleString(\Twig_NodeInterface $body)
{
foreach ($body as $i => $node) {
if (
$node instanceof \Twig_Node_Text
||
($node instanceof \Twig_Node_Print && $node->expr instanceof \Twig_Node_Expression_Name)
) {
continue;
}
return false;
}
return true;
}
}

View File

@ -32,10 +32,20 @@ class TransChoiceTokenParser extends TransTokenParser
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$vars = null;
$count = $this->parser->getExpressionParser()->parseExpression();
$domain = new \Twig_Node_Expression_Constant('messages', $lineno);
if (!$stream->test(\Twig_Token::BLOCK_END_TYPE) && $stream->test('from')) {
if ($stream->test('with')) {
// {% transchoice count with vars %}
$stream->next();
$vars = $this->parser->getExpressionParser()->parseExpression();
}
if ($stream->test('from')) {
// {% transchoice count from "messages" %}
$stream->next();
$domain = $this->parser->getExpressionParser()->parseExpression();
}
@ -46,9 +56,7 @@ class TransChoiceTokenParser extends TransTokenParser
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
$this->checkTransString($body, $lineno);
return new TransNode($body, $domain, $count, $lineno, $this->getTag());
return new TransNode($body, $domain, $count, $vars, $lineno, $this->getTag());
}
public function decideTransChoiceFork($token)

View File

@ -32,14 +32,22 @@ class TransTokenParser extends \Twig_TokenParser
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$vars = null;
$domain = new \Twig_Node_Expression_Constant('messages', $lineno);
if (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) {
$body = null;
if (!$stream->test('from')) {
// {% trans "message" %}
// {% trans message %}
$body = $this->parser->getExpressionParser()->parseExpression();
}
if ($stream->test('with')) {
// {% trans "message" with vars %}
$stream->next();
$vars = $this->parser->getExpressionParser()->parseExpression();
}
if ($stream->test('from')) {
// {% trans "message" from "messages" %}
$stream->next();
@ -61,9 +69,7 @@ class TransTokenParser extends \Twig_TokenParser
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
$this->checkTransString($body, $lineno);
return new TransNode($body, $domain, null, $lineno, $this->getTag());
return new TransNode($body, $domain, null, $vars, $lineno, $this->getTag());
}
public function decideTransFork($token)
@ -80,19 +86,4 @@ class TransTokenParser extends \Twig_TokenParser
{
return 'trans';
}
protected function checkTransString(\Twig_NodeInterface $body, $lineno)
{
foreach ($body as $i => $node) {
if (
$node instanceof \Twig_Node_Text
||
($node instanceof \Twig_Node_Print && $node->expr instanceof \Twig_Node_Expression_Name)
) {
continue;
}
throw new \Twig_SyntaxError(sprintf('The text to be translated with "trans" can only contain references to simple variables'), $lineno);
}
}
}