Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Symfony's TranslatableInterface in enum fields #8212

Merged
merged 3 commits into from
Nov 13, 2024

Conversation

zyberspace
Copy link
Contributor

@zyberspace zyberspace commented Oct 20, 2024

Support Symfony's TranslatableInterface in enum fields

Fixes the translation of enums implementing Symfony's TranslatableInterface.

Right now there is a discrepancy between how the Symfony EnumType form type translates enums and how Sonata Admin translates them. The EnumType uses the enum case's name by default for the choice labels. If you need anything else, your enum has to implement the TranslatableInterface and a trans() method like in the third example on the docs page: https://symfony.com/doc/current/reference/forms/types/enum.html#example-usage

However the FieldDescriptionInterface::TYPE_ENUM field type completely ignores this and instead implements the options use_value and enum_translation_domain, which severely limits how the enum can be translated. I for example often use the format enum.[ENUM_SHORT_NAME].[ENUM_VALUE] which is not possible with the current implementation.

With this PR, the FieldDescriptionInterface::TYPE_ENUM field type will use the enum's trans() method if available to translate the enum and therefore use the same logic, Symfony's EnumType uses.

With this PR, using enums is as easy as:

enum Salutation implements TranslatableInterface
{
    /* case ... = ...; */

    public function trans(TranslatorInterface $translator, ?string $locale = null): string
    {
        // Implement your custom enum translation logic here
        return $translator->trans('enum.saluation.'.$this->value, locale: $locale);
    }
}
protected function configureListFields(ListMapper $list): void
{
    $list
        ->add('saluation')
    ;
}

protected function configureFormFields(FormMapper $form): void
{
    $form
        ->add('salutation', EnumType::class, [
            'class' => Salutation::class,
        ])
    ;
}

protected function configureShowFields(ShowMapper $show): void
{
    $show
        ->add('salutation')
    ;
}

I also added tests for the previous translation method, as there were none.

I am targeting the 4.x branch, because people using enums with the TranslatableInterface currently can not use the enum field type anyway, as it would use the wrong translation, so there should be no backwards compatible issues here.

Changelog

### Changed
- Enums implementing Symfony's `TranslatableInterface` are now correctly translated by the `FieldDescriptionInterface::TYPE_ENUM` field type

@zyberspace zyberspace changed the title Support symfony TranslatableInterface in enum fields Support Symfony's TranslatableInterface in enum fields Oct 20, 2024
@virtualize
Copy link
Contributor

@VincentLanglet could you please have a look at this PR?

@zyberspace
Copy link
Contributor Author

Will rebase as soon as #8215 is merged. Should fix the checks.

@VincentLanglet
Copy link
Member

Hi, it can be rebased

@zyberspace zyberspace force-pushed the feature/translate-enums branch from cc55b04 to f7687fb Compare November 13, 2024 10:49
@zyberspace
Copy link
Contributor Author

@VincentLanglet Done. And thanks for fixing the build!

Can you approve the workflow a second time? Thanks!

@VincentLanglet VincentLanglet merged commit bed2aaf into sonata-project:4.x Nov 13, 2024
24 checks passed
@VincentLanglet
Copy link
Member

Thanks @zyberspace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants