From 9ed19d948fd785e9428d0a4fbce9301df0f338c1 Mon Sep 17 00:00:00 2001 From: Stanislau Kviatkouski <7zete7@gmail.com> Date: Thu, 26 Sep 2024 13:33:10 +0300 Subject: [PATCH] [TwigBridge] Fixed a parameterized choice label translation --- .../Bridge/Twig/Extension/FormExtension.php | 12 ++-- .../FormExtensionFieldHelpersTest.php | 59 +++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Extension/FormExtension.php b/src/Symfony/Bridge/Twig/Extension/FormExtension.php index 673f8199f9a2a..01f65ec202bee 100644 --- a/src/Symfony/Bridge/Twig/Extension/FormExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/FormExtension.php @@ -19,6 +19,7 @@ use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormRenderer; use Symfony\Component\Form\FormView; +use Symfony\Contracts\Translation\TranslatableInterface; use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; @@ -149,23 +150,26 @@ public function getFieldChoices(FormView $view): iterable private function createFieldChoicesList(iterable $choices, string|false|null $translationDomain): iterable { foreach ($choices as $choice) { - $translatableLabel = $this->createFieldTranslation($choice->label, [], $translationDomain); - if ($choice instanceof ChoiceGroupView) { + $translatableLabel = $this->createFieldTranslation($choice->label, [], $translationDomain); yield $translatableLabel => $this->createFieldChoicesList($choice, $translationDomain); continue; } /* @var ChoiceView $choice */ + $translatableLabel = $this->createFieldTranslation($choice->label, $choice->labelTranslationParameters, $translationDomain); yield $translatableLabel => $choice->value; } } - private function createFieldTranslation(?string $value, array $parameters, string|false|null $domain): ?string + private function createFieldTranslation(TranslatableInterface|string|null $value, array $parameters, string|false|null $domain): ?string { if (!$this->translator || !$value || false === $domain) { - return $value; + return null !== $value ? (string) $value : null; + } + if ($value instanceof TranslatableInterface) { + return $value->trans($this->translator); } return $this->translator->trans($value, $parameters, $domain); diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionFieldHelpersTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionFieldHelpersTest.php index 8e2c0298328e5..b65b53a0d3dfa 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionFieldHelpersTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionFieldHelpersTest.php @@ -19,6 +19,7 @@ use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormView; use Symfony\Component\Form\Test\FormIntegrationTestCase; +use Symfony\Component\Translation\TranslatableMessage; class FormExtensionFieldHelpersTest extends FormIntegrationTestCase { @@ -81,6 +82,28 @@ protected function setUp(): void 'expanded' => true, 'label' => false, ]) + ->add('parametrized_choice_label', ChoiceType::class, [ + 'choices' => [ + (object) ['value' => 'yes', 'label' => 'parametrized.%yes%'], + (object) ['value' => 'no', 'label' => 'parametrized.%no%'], + ], + 'choice_value' => 'value', + 'choice_label' => 'label', + 'choice_translation_domain' => 'forms', + 'choice_translation_parameters' => [ + ['%yes%' => 'YES'], + ['%no%' => 'NO'], + ], + ]) + ->add('translatable_choice_label', ChoiceType::class, [ + 'choices' => [ + 'yes', + 'no', + ], + 'choice_label' => static function (string $choice) { + return new TranslatableMessage('parametrized.%value%', ['%value%' => $choice], 'forms'); + }, + ]) ->getForm() ; @@ -290,4 +313,40 @@ public function testFieldTranslatedChoicesMultiple() $this->assertSame('salt', $choicesArray[1]['value']); $this->assertSame('[trans]base.salt[/trans]', $choicesArray[1]['label']); } + + public function testChoiceParametrizedLabel() + { + $choices = $this->translatorExtension->getFieldChoices($this->view->children['parametrized_choice_label']); + + $choicesArray = []; + foreach ($choices as $label => $value) { + $choicesArray[] = ['label' => $label, 'value' => $value]; + } + + $this->assertCount(2, $choicesArray); + + $this->assertSame('yes', $choicesArray[0]['value']); + $this->assertSame('[trans]parametrized.YES[/trans]', $choicesArray[0]['label']); + + $this->assertSame('no', $choicesArray[1]['value']); + $this->assertSame('[trans]parametrized.NO[/trans]', $choicesArray[1]['label']); + } + + public function testChoiceTranslatableLabel() + { + $choices = $this->translatorExtension->getFieldChoices($this->view->children['translatable_choice_label']); + + $choicesArray = []; + foreach ($choices as $label => $value) { + $choicesArray[] = ['label' => $label, 'value' => $value]; + } + + $this->assertCount(2, $choicesArray); + + $this->assertSame('yes', $choicesArray[0]['value']); + $this->assertSame('[trans]parametrized.yes[/trans]', $choicesArray[0]['label']); + + $this->assertSame('no', $choicesArray[1]['value']); + $this->assertSame('[trans]parametrized.no[/trans]', $choicesArray[1]['label']); + } }