symfonylocalizationinternationalizationsymfony2-easyadmin

Symfony: How to use translation component in entity __toString?


Yes, I know this has been asked before and discouraged, but I have a good use case for that. I am interested in learning the view-oriented supplementary approach.

The use case:

I have an entity, say Venue (id, name, capacity) which I use as collection in EasyAdmin. To render choices, I require this entity to have string representation.

I want the display to say %name% (%capacity% places).

As you've correctly guessed, I require the word "places" translated.

I could want to do it

  1. directly in the entity's __toString() method
  2. in form view by properly rendering __toString() output

I have no idea how to implement either but I agree that the first approach violates the MVC pattern.

Please advise.


Solution

  • Displaying it as %name% (%capacity% places) is just a "possible" representation in your form view so I would shift this very specific representation to your Form Type.

    What can belong in the __toString() method of your Venue entity:

    class Venue 
    {
        private $name;
    
        ... setter & getter method
    
        public function __toString()
        {
            return $this->getName();
        }
    }
    

    messages.en.yml:

    my_translation: %name% (%capacity% places)
    

    Next your Form Type using choice_label (also worth knowing: choice_translation_domain) :

    use Symfony\Component\Translation\TranslatorInterface;
    
    class YourFormType extends AbstractType
    {
        private $translator;
    
        public function __construct(TranslatorInterface $translator)
        {
            $this->translator = $translator;
        }
    
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add(
                    'venue',
                    EntityType::class,
                    array(
                        'choice_label' => function (Venue $venue, $key, $index) {
                            // Translatable choice labels
                            return $this->translator->trans('my_translation', array(
                                '%name%' => $venue->getName(),
                                '%capacity%' => $venue->getCapacity(),
                            ));
                        }
                    )
                );
        }
    
    }
    

    & also register your form type as a service in services.yml:

    your_form_type:
      class: Your\Bundle\Namespace\Form\YourFormType
      arguments: ["@translator"]
      tags:
        - { name: form.type }