added a way to translate strings coming from a variable ({% trans var %}) (closes #69)

This commit is contained in:
Fabien Potencier
2010-06-28 15:10:52 +02:00
parent cccaf5583a
commit 2c1eb31021
5 changed files with 67 additions and 29 deletions
+6
View File
@@ -1,5 +1,11 @@
* 0.9.8
Backward incompatibilities:
* the trans tag plural count is now attached to the plural tag:
old: `{% trans count %}...{% plural %}...{% endtrans %}`
new: `{% trans %}...{% plural count %}...{% endtrans %}`
* added a way to translate strings coming from a variable ({% trans var %})
* fixed trans tag when used with the Escaper extension
* fixed default cache umask
* removed Twig_Template instances from the debug tag output
+17 -10
View File
@@ -824,8 +824,12 @@ When the `i18n` extension is enabled, use the `trans` block to mark parts in
the template as translatable:
[twig]
{% trans "Hello World!" %}
{% trans string_var %}
{% trans %}
Hello World!
Hello World!
{% endtrans %}
>**CAUTION**
@@ -836,9 +840,12 @@ In a translatable string, you can embed variables:
[twig]
{% trans %}
Hello {{ name }}!
Hello {{ name }}!
{% endtrans %}
>**NOTE**
>`{% trans "Hello {{ name }}!" %}` is not a valid statement.
If you need to apply filters to the variables, you first need to assign the
result to a variable:
@@ -846,21 +853,21 @@ result to a variable:
{% set name as name|capitalize %}
{% trans %}
Hello {{ name }}!
Hello {{ name }}!
{% endtrans %}
To pluralize a translatable string, use the `plural` block:
[twig]
{% trans apple_count %}
Hey {{ name }}, I have one apple.
{% plural %}
Hey {{ name }}, I have {{ count }} apples.
{% trans %}
Hey {{ name }}, I have one apple.
{% plural apple_count %}
Hey {{ name }}, I have {{ count }} apples.
{% endtrans %}
The `trans` block first argument is the `count` used to select the right
string. Within the translatable string, the special `count` variable always
contain the count value (here the value of `apple_count`).
The `plural` tag should provide the `count` used to select the right string.
Within the translatable string, the special `count` variable always contain
the count value (here the value of `apple_count`).
Expressions
-----------
+12 -8
View File
@@ -45,13 +45,13 @@ class Twig_Node_Trans extends Twig_Node
if ($vars) {
$compiler
->write('echo strtr('.$function.'(')
->string($msg)
->subcompile($msg)
;
if (null !== $this->plural) {
$compiler
->raw(', ')
->string($msg1)
->subcompile($msg1)
->raw(', abs(')
->subcompile($this->count)
->raw(')')
@@ -82,7 +82,7 @@ class Twig_Node_Trans extends Twig_Node
} else {
$compiler
->write('echo '.$function.'(')
->string($msg)
->subcompile($msg)
->raw(");\n")
;
}
@@ -90,21 +90,25 @@ class Twig_Node_Trans extends Twig_Node
protected function compileString(Twig_NodeInterface $body)
{
if ($body instanceof Twig_Node_Expression_Name || $body instanceof Twig_Node_Expression_Constant) {
return array($body, array());
}
$msg = '';
$vars = array();
foreach ($body as $i => $node) {
if ($node instanceof Twig_Node_Text) {
$msg .= $node['data'];
} else {
foreach ($body as $node) {
if ($node instanceof Twig_Node_Print) {
$n = $node->expr;
while ($n instanceof Twig_Node_Expression_Filter) {
$n = $n->node;
}
$msg .= sprintf('%%%s%%', $n['name']);
$vars[] = new Twig_Node_Expression_Name($n['name'], $n->getLine());
} else {
$msg .= $node['data'];
}
}
return array(trim($msg), $vars);
return array(new Twig_Node(array(new Twig_Node_Expression_Constant(trim($msg), $node->getLine()))), $vars);
}
}
+9 -11
View File
@@ -22,19 +22,17 @@ class Twig_TokenParser_Trans extends Twig_TokenParser
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$count = null;
if (!$stream->test(Twig_Token::BLOCK_END_TYPE)) {
$count = new Twig_Node_Expression_Name($stream->expect(Twig_Token::NAME_TYPE)->getValue(), $lineno);
}
$stream->expect(Twig_Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideForFork'));
$plural = null;
if ('plural' === $stream->next()->getValue()) {
$stream->expect(Twig_Token::BLOCK_END_TYPE);
$plural = $this->parser->subparse(array($this, 'decideForEnd'), true);
if (null === $count) {
throw new Twig_SyntaxError('When a plural is used, you must pass the count as an argument to the "trans" tag', $lineno);
if (!$stream->test(Twig_Token::BLOCK_END_TYPE)) {
$body = $this->parser->getExpressionParser()->parseExpression();
} else {
$stream->expect(Twig_Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideForFork'));
if ('plural' === $stream->next()->getValue()) {
$count = new Twig_Node_Expression_Name($stream->expect(Twig_Token::NAME_TYPE)->getValue(), $lineno);
$stream->expect(Twig_Token::BLOCK_END_TYPE);
$plural = $this->parser->subparse(array($this, 'decideForEnd'), true);
}
}
+23
View File
@@ -40,6 +40,14 @@ class Twig_Tests_Node_TransTest extends Twig_Tests_Node_TestCase
{
$tests = array();
$body = new Twig_Node_Expression_Name('foo', 0);
$node = new Twig_Node_Trans($body, null, null, 0);
$tests[] = array($node, 'echo gettext((isset($context[\'foo\']) ? $context[\'foo\'] : null));');
$body = new Twig_Node_Expression_Constant('Hello', 0);
$node = new Twig_Node_Trans($body, null, null, 0);
$tests[] = array($node, 'echo gettext("Hello");');
$body = new Twig_Node(array(
new Twig_Node_Text('Hello', 0),
), array(), 0);
@@ -70,6 +78,21 @@ class Twig_Tests_Node_TransTest extends Twig_Tests_Node_TestCase
$node = new Twig_Node_Trans($body, $plural, $count, 0);
$tests[] = array($node, 'echo strtr(ngettext("Hey %name%, I have one apple", "Hey %name%, I have %count% apples", abs(12)), array("%name%" => (isset($context[\'name\']) ? $context[\'name\'] : null), "%name%" => (isset($context[\'name\']) ? $context[\'name\'] : null), "%count%" => abs(12), ));');
// with escaper extension set to on
$filters = new Twig_Node(array(
new Twig_Node_Expression_Constant('escape', 0),
new Twig_Node(),
), array(), 0);
$body = new Twig_Node(array(
new Twig_Node_Text('J\'ai ', 0),
new Twig_Node_Print(new Twig_Node_Expression_Filter(new Twig_Node_Expression_Name('foo', 0), $filters, 0), 0),
new Twig_Node_Text(' pommes', 0),
), array(), 0);
$node = new Twig_Node_Trans($body, null, null, 0);
$tests[] = array($node, 'echo strtr(gettext("J\'ai %foo% pommes"), array("%foo%" => (isset($context[\'foo\']) ? $context[\'foo\'] : null), ));');
return $tests;
}
}