symfonytranslationsymfony-formssymfony6

translation:extract is not working in forms


Regarding this form:

<?php
// src/Form/ContacteType.php

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Translation\TranslatableMessage;
class ContacteType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $message = new TranslatableMessage('Symfony is great!');
        $builder
            ->add('nom', TextType::class)
            
           
            ->add('email', EmailType::class, [
                'attr' => ['class' => 'form-control mb-3 mb-md-0', 'placeholder' => 'E-mail'],
            ])
            ->add('tipus', ChoiceType::class, [
                'choices' => [
                    'contacte.necessito.llogar' => 'llogar',
                    'contacte.necessito.comprar' => 'comprar'
                ],
                'choice_label' => fn ($choice, $key, $value) => $key,
                'placeholder' => 'contacte.necessito.placeholder',
                'translation_domain' => 'messages',
                'attr' => [
                    'class' => 'form-select mb-3',
                    'data-controller' => 'choices',
                    'data-choices-inner-class-value' => 'form-select',
                    'data-choices-outer-class-value' => 'choices' // opcional, pots ometre o personalitzar-lo
                ],
            ])

            ->add('missatge', TextareaType::class, [
                'attr' => ['class' => 'form-control', 'rows' => 6, 'placeholder' => 'Missatge'],
            ])
            ->add('acceptar', CheckboxType::class, [
                'mapped' => false,
                'attr' => ['class' => 'form-check-input'],
            ])
            ->add('submit', SubmitType::class, [
                'label' => 'Envia',
                'attr' => ['class' => 'btn btn-primary d-block mt-4'],
            ]);
    }
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'translation_domain' => 'messages',
        ]);      
    }
}

When I execute the command line php bin/console translation:extract ca --force , It extracts the message ot this line: $message = new TranslatableMessage('Symfony is great!');. but it doesn't extract any other message (labels, placeholders, etc.) In the past, in the same project, it did, but now, I don't know why, it doesn't. If I add manually the message in the translation file, the translation is done properly.

My composer:

{

    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "symfony/asset": "6.4.*",
        "symfony/console": "6.4.*",
        "symfony/dotenv": "6.4.*",
        "symfony/expression-language": "6.4.*",
        "symfony/flex": "^2",
        "symfony/form": "6.4.*",
        "symfony/intl": "6.4.*",
        "symfony/translation": "6.4.*",
        "symfony/twig-bundle": "6.4.*",
        "symfony/ux-turbo": "^2.24",
        "symfony/ux-twig-component": "*",
        "symfony/validator": "6.4.*",
        "symfony/web-link": "6.4.*",
        "symfony/yaml": "6.4.*",
        "twig/extra-bundle": "^3.21",
        "twig/intl-extra": "^3.21",
        "twig/twig": "^2.12|^3.0",

    },

Solution

  • I'm not too up-to-date on what accepted best practices are, but I inject TranslatorInterface into forms.

    The auto-extraction of form labels through translation:extract, without using the aformentioned TranslatorInterface never worked for me either.

        public function __construct(TranslatorInterface $translator)
        {
            $this->translator = $translator;
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options): void
        {
            $builder = new DynamicFormBuilder($builder);
    
            $builder
                ->add('type', ChoiceType::class, [
                    'label' => $this->translator->trans('Type'),