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 7cdef58

Browse filesBrowse files
Make trans + %count% parameter resolve plurals
1 parent 640a887 commit 7cdef58
Copy full SHA for 7cdef58

38 files changed

+890
-435
lines changed

‎UPGRADE-4.2.md

Copy file name to clipboardExpand all lines: UPGRADE-4.2.md
+8-3Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ FrameworkBundle
108108
serializer:
109109
id: your_messenger_service_id
110110
```
111-
* The `ContainerAwareCommand` class has been deprecated, use `Symfony\Component\Console\Command\Command`
112-
with dependency injection instead.
111+
* The `ContainerAwareCommand` class has been deprecated, use `Symfony\Component\Console\Command\Command` with dependency injection instead.
112+
* The `Templating\Helper\TranslatorHelper::transChoice()` method has been deprecated, use the `trans()` one instead with a `%count%` parameter.
113113

114114
Messenger
115115
---------
@@ -208,9 +208,14 @@ Translation
208208
-----------
209209

210210
* The `TranslatorInterface` has been deprecated in favor of `Symfony\Contracts\Translation\TranslatorInterface`
211-
* The `Translator::transChoice()` has been deprecated in favor of using `Translator::trans()` with intl message format
211+
* The `Translator::transChoice()` has been deprecated in favor of using `Translator::trans()` with "count" as the parameter driving plurals
212212
* The `MessageSelector`, `Interval` and `PluralizationRules` classes have been deprecated, use `IdentityTranslator` instead
213213

214+
TwigBundle
215+
----------
216+
217+
* The `transchoice` tag and filter have been deprecated, use the `trans` ones instead with a `%count%` parameter.
218+
214219
Validator
215220
---------
216221

‎UPGRADE-5.0.md

Copy file name to clipboardExpand all lines: UPGRADE-5.0.md
+4-2Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ FrameworkBundle
114114
* The `RequestDataCollector` class has been removed. Use the `Symfony\Component\HttpKernel\DataCollector\RequestDataCollector` class instead.
115115
* Removed `Symfony\Bundle\FrameworkBundle\Controller\Controller`. Use `Symfony\Bundle\FrameworkBundle\Controller\AbstractController` instead.
116116
* Added support for the SameSite attribute for session cookies. It is highly recommended to set this setting (`framework.session.cookie_samesite`) to `lax` for increased security against CSRF attacks.
117-
* The `ContainerAwareCommand` class has been removed, use `Symfony\Component\Console\Command\Command`
118-
with dependency injection instead.
117+
* The `ContainerAwareCommand` class has been removed, use `Symfony\Component\Console\Command\Command` with dependency injection instead.
118+
* The `Templating\Helper\TranslatorHelper::transChoice()` method has been removed, use the `trans()` one instead with a `%count%` parameter.
119119

120120
HttpFoundation
121121
--------------
@@ -184,11 +184,13 @@ Translation
184184
* The `TranslationWriter::disableBackup()` method has been removed.
185185
* The `TranslatorInterface` has been removed in favor of `Symfony\Contracts\Translation\TranslatorInterface`
186186
* The `MessageSelector`, `Interval` and `PluralizationRules` classes have been removed, use `IdentityTranslator` instead
187+
* The `Translator::transChoice()` method has been removed in favor of using `Translator::trans()` with "count" as the parameter driving plurals
187188

188189
TwigBundle
189190
----------
190191

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

193195
Validator
194196
--------

‎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.