Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dc5f3bf

Browse filesBrowse files
Make trans + %count% parameter resolve plurals
1 parent d870a85 commit dc5f3bf
Copy full SHA for dc5f3bf

38 files changed

+888
-431
lines changed

‎UPGRADE-4.2.md

Copy file name to clipboardExpand all lines: UPGRADE-4.2.md
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ FrameworkBundle
114114
set the "APP_ENV" environment variable instead.
115115
* The `--no-debug` console option has been deprecated,
116116
set the "APP_DEBUG" environment variable to "0" instead.
117+
* The `Templating\Helper\TranslatorHelper::transChoice()` method has been deprecated, use the `trans()` one instead with a `%count%` parameter.
117118

118119
Messenger
119120
---------
@@ -219,10 +220,15 @@ Translation
219220
-----------
220221

221222
* The `TranslatorInterface` has been deprecated in favor of `Symfony\Contracts\Translation\TranslatorInterface`
222-
* The `Translator::transChoice()` has been deprecated in favor of using `Translator::trans()` with intl message format
223+
* The `Translator::transChoice()` method has been deprecated in favor of using `Translator::trans()` with "%count%" as the parameter driving plurals
223224
* The `MessageSelector`, `Interval` and `PluralizationRules` classes have been deprecated, use `IdentityTranslator` instead
224225
* The `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` method have been marked as internal
225226

227+
TwigBundle
228+
----------
229+
230+
* The `transchoice` tag and filter have been deprecated, use the `trans` ones instead with a `%count%` parameter.
231+
226232
Validator
227233
---------
228234

‎UPGRADE-5.0.md

Copy file name to clipboardExpand all lines: UPGRADE-5.0.md
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ FrameworkBundle
120120
set the "APP_ENV" environment variable instead.
121121
* The `--no-debug` console option has been removed,
122122
set the "APP_DEBUG" environment variable to "0" instead.
123+
* The `Templating\Helper\TranslatorHelper::transChoice()` method has been removed, use the `trans()` one instead with a `%count%` parameter.
123124

124125
HttpFoundation
125126
--------------
@@ -196,11 +197,13 @@ Translation
196197
* The `TranslatorInterface` has been removed in favor of `Symfony\Contracts\Translation\TranslatorInterface`
197198
* The `MessageSelector`, `Interval` and `PluralizationRules` classes have been removed, use `IdentityTranslator` instead
198199
* The `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` method are now internal
200+
* The `Translator::transChoice()` method has been removed in favor of using `Translator::trans()` with "%count%" as the parameter driving plurals
199201

200202
TwigBundle
201203
----------
202204

203205
* The default value (`false`) of the `twig.strict_variables` configuration option has been changed to `%kernel.debug%`.
206+
* The `transchoice` tag and filter have been removed, use the `trans` ones instead with a `%count%` parameter.
204207

205208
Validator
206209
--------

‎src/Symfony/Bridge/Twig/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/CHANGELOG.md
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ CHANGELOG
44
4.2.0
55
-----
66

7-
* add bundle name suggestion on wrongly overridden templates paths
8-
* added `name` argument in `debug:twig` command and changed `filter` argument as `--filter` option
7+
* add bundle name suggestion on wrongly overridden templates paths
8+
* added `name` argument in `debug:twig` command and changed `filter` argument as `--filter` option
9+
* deprecated the `transchoice` tag and filter, use the `trans` ones instead with a `%count%` parameter
910

1011
4.1.0
1112
-----

‎src/Symfony/Bridge/Twig/Extension/TranslationExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Extension/TranslationExtension.php
+27-10Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use Symfony\Bridge\Twig\TokenParser\TransChoiceTokenParser;
1717
use Symfony\Bridge\Twig\TokenParser\TransDefaultDomainTokenParser;
1818
use Symfony\Bridge\Twig\TokenParser\TransTokenParser;
19-
use Symfony\Component\Translation\LegacyTranslatorTrait;
2019
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
2120
use Symfony\Contracts\Translation\TranslatorInterface;
2221
use Symfony\Contracts\Translation\TranslatorTrait;
@@ -29,6 +28,8 @@
2928
* Provides integration of the Translation component with Twig.
3029
*
3130
* @author Fabien Potencier <fabien@symfony.com>
31+
*
32+
* @final since Symfony 4.2
3233
*/
3334
class TranslationExtension extends AbstractExtension
3435
{
@@ -38,21 +39,28 @@ class TranslationExtension extends AbstractExtension
3839
trans as private doTrans;
3940
}
4041

41-
use LegacyTranslatorTrait {
42-
transChoice as private doTransChoice;
43-
}
44-
4542
private $translator;
4643
private $translationNodeVisitor;
4744

48-
public function __construct(TranslatorInterface $translator = null, NodeVisitorInterface $translationNodeVisitor = null)
45+
/**
46+
* @param TranslatorInterface|null $translator
47+
*/
48+
public function __construct($translator = null, NodeVisitorInterface $translationNodeVisitor = null)
4949
{
50+
if (null !== $translator && !$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) {
51+
throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator)));
52+
}
5053
$this->translator = $translator;
5154
$this->translationNodeVisitor = $translationNodeVisitor;
5255
}
5356

57+
/**
58+
* @deprecated since Symfony 4.2
59+
*/
5460
public function getTranslator()
5561
{
62+
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
63+
5664
return $this->translator;
5765
}
5866

@@ -63,7 +71,7 @@ public function getFilters()
6371
{
6472
return array(
6573
new TwigFilter('trans', array($this, 'trans')),
66-
new TwigFilter('transchoice', array($this, 'transchoice')),
74+
new TwigFilter('transchoice', array($this, 'transchoice'), array('deprecated' => '4.2', 'alternative' => 'trans" with parameter "%count%')),
6775
);
6876
}
6977

@@ -101,19 +109,28 @@ public function getTranslationNodeVisitor()
101109
return $this->translationNodeVisitor ?: $this->translationNodeVisitor = new TranslationNodeVisitor();
102110
}
103111

104-
public function trans($message, array $arguments = array(), $domain = null, $locale = null)
112+
public function trans($message, array $arguments = array(), $domain = null, $locale = null, $count = null)
105113
{
114+
if (null !== $count) {
115+
$arguments['%count%'] = $count;
116+
}
106117
if (null === $this->translator) {
107118
return $this->doTrans($message, $arguments, $domain, $locale);
108119
}
109120

110121
return $this->translator->trans($message, $arguments, $domain, $locale);
111122
}
112123

124+
/**
125+
* @deprecated since Symfony 4.2, use the trans() method instead with a %count% parameter
126+
*/
113127
public function transchoice($message, $count, array $arguments = array(), $domain = null, $locale = null)
114128
{
115-
if (null === $this->translator || !$this->translator instanceof LegacyTranslatorInterface) {
116-
return $this->doTransChoice($message, $count, array_merge(array('%count%' => $count), $arguments), $domain, $locale);
129+
if (null === $this->translator) {
130+
return $this->doTrans($message, array_merge(array('%count%' => $count), $arguments), $domain, $locale);
131+
}
132+
if ($this->translator instanceof TranslatorInterface) {
133+
return $this->translator->trans($message, array_merge(array('%count%' => $count), $arguments), $domain, $locale);
117134
}
118135

119136
return $this->translator->transChoice($message, $count, array_merge(array('%count%' => $count), $arguments), $domain, $locale);

‎src/Symfony/Bridge/Twig/Node/TransNode.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Node/TransNode.php
+11-8Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,12 @@ public function compile(Compiler $compiler)
6060
$method = !$this->hasNode('count') ? 'trans' : 'transChoice';
6161

6262
$compiler
63-
->write('echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->getTranslator()->'.$method.'(')
63+
->write('echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->trans(')
6464
->subcompile($msg)
6565
;
6666

6767
$compiler->raw(', ');
6868

69-
if ($this->hasNode('count')) {
70-
$compiler
71-
->subcompile($this->getNode('count'))
72-
->raw(', ')
73-
;
74-
}
75-
7669
if (null !== $vars) {
7770
$compiler
7871
->raw('array_merge(')
@@ -98,7 +91,17 @@ public function compile(Compiler $compiler)
9891
->raw(', ')
9992
->subcompile($this->getNode('locale'))
10093
;
94+
} elseif ($this->hasNode('count')) {
95+
$compiler->raw(', null');
10196
}
97+
98+
if ($this->hasNode('count')) {
99+
$compiler
100+
->raw(', ')
101+
->subcompile($this->getNode('count'))
102+
;
103+
}
104+
102105
$compiler->raw(");\n");
103106
}
104107

‎src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php
+79-6Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ public function testTrans($template, $expected, array $variables = array())
4545
$this->assertEquals($expected, $this->getTemplate($template)->render($variables));
4646
}
4747

48+
/**
49+
* @group legacy
50+
* @dataProvider getTransChoiceTests
51+
*/
52+
public function testTransChoice($template, $expected, array $variables = array())
53+
{
54+
$this->testTrans($template, $expected, $variables);
55+
}
56+
4857
/**
4958
* @expectedException \Twig\Error\SyntaxError
5059
* @expectedExceptionMessage Unexpected token. Twig was looking for the "with", "from", or "into" keyword in "index" at line 3.
@@ -64,6 +73,7 @@ public function testTransComplexBody()
6473
}
6574

6675
/**
76+
* @group legacy
6777
* @expectedException \Twig\Error\SyntaxError
6878
* @expectedExceptionMessage A message inside a transchoice tag must be a simple text in "index" at line 2.
6979
*/
@@ -87,6 +97,69 @@ public function getTransTests()
8797

8898
array('{% trans into "fr"%}Hello{% endtrans %}', 'Hello'),
8999

100+
// trans with count
101+
array(
102+
'{% trans from "messages" %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtrans %}',
103+
'There is no apples',
104+
array('count' => 0),
105+
),
106+
array(
107+
'{% trans %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtrans %}',
108+
'There is 5 apples',
109+
array('count' => 5),
110+
),
111+
array(
112+
'{% trans %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%){% endtrans %}',
113+
'There is 5 apples (Symfony)',
114+
array('count' => 5, 'name' => 'Symfony'),
115+
),
116+
array(
117+
'{% trans with { \'%name%\': \'Symfony\' } %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%){% endtrans %}',
118+
'There is 5 apples (Symfony)',
119+
array('count' => 5),
120+
),
121+
array(
122+
'{% trans into "fr"%}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtrans %}',
123+
'There is no apples',
124+
array('count' => 0),
125+
),
126+
array(
127+
'{% trans count 5 into "fr"%}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtrans %}',
128+
'There is 5 apples',
129+
),
130+
131+
// trans filter
132+
array('{{ "Hello"|trans }}', 'Hello'),
133+
array('{{ name|trans }}', 'Symfony', array('name' => 'Symfony')),
134+
array('{{ hello|trans({ \'%name%\': \'Symfony\' }) }}', 'Hello Symfony', array('hello' => 'Hello %name%')),
135+
array('{% set vars = { \'%name%\': \'Symfony\' } %}{{ hello|trans(vars) }}', 'Hello Symfony', array('hello' => 'Hello %name%')),
136+
array('{{ "Hello"|trans({}, "messages", "fr") }}', 'Hello'),
137+
138+
// trans filter with count
139+
array('{{ "{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples"|trans(count=count) }}', 'There is 5 apples', array('count' => 5)),
140+
array('{{ text|trans(count=5, arguments={\'%name%\': \'Symfony\'}) }}', 'There is 5 apples (Symfony)', array('text' => '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%)')),
141+
array('{{ "{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples"|trans({}, "messages", "fr", count) }}', 'There is 5 apples', array('count' => 5)),
142+
);
143+
}
144+
145+
/**
146+
* @group legacy
147+
*/
148+
public function getTransChoiceTests()
149+
{
150+
return array(
151+
// trans tag
152+
array('{% trans %}Hello{% endtrans %}', 'Hello'),
153+
array('{% trans %}%name%{% endtrans %}', 'Symfony', array('name' => 'Symfony')),
154+
155+
array('{% trans from elsewhere %}Hello{% endtrans %}', 'Hello'),
156+
157+
array('{% trans %}Hello %name%{% endtrans %}', 'Hello Symfony', array('name' => 'Symfony')),
158+
array('{% trans with { \'%name%\': \'Symfony\' } %}Hello %name%{% endtrans %}', 'Hello Symfony'),
159+
array('{% set vars = { \'%name%\': \'Symfony\' } %}{% trans with vars %}Hello %name%{% endtrans %}', 'Hello Symfony'),
160+
161+
array('{% trans into "fr"%}Hello{% endtrans %}', 'Hello'),
162+
90163
// transchoice
91164
array(
92165
'{% transchoice count from "messages" %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtranschoice %}',
@@ -145,8 +218,8 @@ public function testDefaultTranslationDomain()
145218
{%- trans from "custom" %}foo{% endtrans %}
146219
{{- "foo"|trans }}
147220
{{- "foo"|trans({}, "custom") }}
148-
{{- "foo"|transchoice(1) }}
149-
{{- "foo"|transchoice(1, {}, "custom") }}
221+
{{- "foo"|trans(count=1) }}
222+
{{- "foo"|trans({"%count%":1}, "custom") }}
150223
{% endblock %}
151224
',
152225

@@ -174,12 +247,12 @@ public function testDefaultTranslationDomainWithNamedArguments()
174247
175248
{%- block content %}
176249
{{- "foo"|trans(arguments = {}, domain = "custom") }}
177-
{{- "foo"|transchoice(count = 1) }}
178-
{{- "foo"|transchoice(count = 1, arguments = {}, domain = "custom") }}
250+
{{- "foo"|trans(count = 1) }}
251+
{{- "foo"|trans(count = 1, arguments = {}, domain = "custom") }}
179252
{{- "foo"|trans({}, domain = "custom") }}
180253
{{- "foo"|trans({}, "custom", locale = "fr") }}
181-
{{- "foo"|transchoice(1, arguments = {}, domain = "custom") }}
182-
{{- "foo"|transchoice(1, {}, "custom", locale = "fr") }}
254+
{{- "foo"|trans(arguments = {"%count%":1}, domain = "custom") }}
255+
{{- "foo"|trans({"%count%":1}, "custom", locale = "fr") }}
183256
{% endblock %}
184257
',
185258

‎src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function testCompileStrict()
3434

3535
$this->assertEquals(
3636
sprintf(
37-
'echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->getTranslator()->trans("trans %%var%%", array_merge(array("%%var%%" => %s), %s), "messages");',
37+
'echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->trans("trans %%var%%", array_merge(array("%%var%%" => %s), %s), "messages");',
3838
$this->getVariableGetterWithoutStrictCheck('var'),
3939
$this->getVariableGetterWithStrictCheck('foo')
4040
),

‎src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php
+26-4Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,21 @@ public function testExtract($template, $messages)
5050
}
5151
}
5252

53+
/**
54+
* @group legacy
55+
* @dataProvider getLegacyExtractData
56+
*/
57+
public function testLegacyExtract($template, $messages)
58+
{
59+
$this->testExtract($template, $messages);
60+
}
61+
5362
public function getExtractData()
5463
{
5564
return array(
5665
array('{{ "new key" | trans() }}', array('new key' => 'messages')),
5766
array('{{ "new key" | trans() | upper }}', array('new key' => 'messages')),
5867
array('{{ "new key" | trans({}, "domain") }}', array('new key' => 'domain')),
59-
array('{{ "new key" | transchoice(1) }}', array('new key' => 'messages')),
60-
array('{{ "new key" | transchoice(1) | upper }}', array('new key' => 'messages')),
61-
array('{{ "new key" | transchoice(1, {}, "domain") }}', array('new key' => 'domain')),
6268
array('{% trans %}new key{% endtrans %}', array('new key' => 'messages')),
6369
array('{% trans %} new key {% endtrans %}', array('new key' => 'messages')),
6470
array('{% trans from "domain" %}new key{% endtrans %}', array('new key' => 'domain')),
@@ -67,11 +73,27 @@ public function getExtractData()
6773

6874
// make sure 'trans_default_domain' tag is supported
6975
array('{% trans_default_domain "domain" %}{{ "new key"|trans }}', array('new key' => 'domain')),
70-
array('{% trans_default_domain "domain" %}{{ "new key"|transchoice }}', array('new key' => 'domain')),
7176
array('{% trans_default_domain "domain" %}{% trans %}new key{% endtrans %}', array('new key' => 'domain')),
7277

7378
// make sure this works with twig's named arguments
7479
array('{{ "new key" | trans(domain="domain") }}', array('new key' => 'domain')),
80+
);
81+
}
82+
83+
/**
84+
* @group legacy
85+
*/
86+
public function getLegacyExtractData()
87+
{
88+
return array(
89+
array('{{ "new key" | transchoice(1) }}', array('new key' => 'messages')),
90+
array('{{ "new key" | transchoice(1) | upper }}', array('new key' => 'messages')),
91+
array('{{ "new key" | transchoice(1, {}, "domain") }}', array('new key' => 'domain')),
92+
93+
// make sure 'trans_default_domain' tag is supported
94+
array('{% trans_default_domain "domain" %}{{ "new key"|transchoice }}', array('new key' => 'domain')),
95+
96+
// make sure this works with twig's named arguments
7597
array('{{ "new key" | transchoice(domain="domain", count=1) }}', array('new key' => 'domain')),
7698
);
7799
}

‎src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* Token Parser for the 'transchoice' tag.
2424
*
2525
* @author Fabien Potencier <fabien@symfony.com>
26+
*
27+
* @deprecated since Symfony 4.2, use the "trans" tag with a "%count%" parameter instead
2628
*/
2729
class TransChoiceTokenParser extends TransTokenParser
2830
{
@@ -38,6 +40,8 @@ public function parse(Token $token)
3840
$lineno = $token->getLine();
3941
$stream = $this->parser->getStream();
4042

43+
@trigger_error(sprintf('The "transchoice" tag is deprecated since Symfony 4.2, use the "trans" one instead with a "%count%" parameter in %s line %d.', $stream->getSourceContext()->getName(), $lineno), E_USER_DEPRECATED);
44+
4145
$vars = new ArrayExpression(array(), $lineno);
4246

4347
$count = $this->parser->getExpressionParser()->parseExpression();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.