@@ -307,40 +307,93 @@ using PHP's :phpclass:`MessageFormatter` class. Read more about this in
307307Translatable Objects
308308--------------------
309309
310- Sometimes translating contents in templates is cumbersome because you need the
311- original message, the translation parameters and the translation domain for
312- each content. Making the translation in the controller or services simplifies
313- your templates, but requires injecting the translator service in different
314- parts of your application and mocking it in your tests.
310+ When it comes to translating a whole application, texts not only come from Twig
311+ templates or controllers but also from constants, services, entities, ...
315312
316- Instead of translating a string at the time of creation, you can use a
317- "translatable object", which is an instance of the
318- :class: `Symfony\\ Component\\ Translation\\ TranslatableMessage ` class. This object stores
319- all the information needed to fully translate its contents when needed::
313+ For example, how you could manage to display a title and a description for each enumeration
314+ cases in your templates::
320315
321- use Symfony\Component\Translation\TranslatableMessage;
316+ .. code-block :: php
322317
323- // the first argument is required and it's the original message
324- $message = new TranslatableMessage('Symfony is great!');
325- // the optional second argument defines the translation parameters and
326- // the optional third argument is the translation domain
327- $status = new TranslatableMessage('order.status', ['%status%' => $order->getStatus()], 'store');
318+ enum UserRoleEnum
319+ {
320+ case USER;
321+ case ADMIN;
322+
323+ public function getTitle(): string
324+ {
325+ return match ($this) {
326+ self::USER => 'User',
327+ self::ADMIN => 'Admin',
328+ };
329+ }
330+
331+ public function getDescription(): string
332+ {
333+ return match ($this) {
334+ self::USER => 'A regular user',
335+ self::ADMIN => 'A super-powered user',
336+ };
337+ }
338+ }
339+
340+ Then from Twig templates you merely call the methods ``roleAdmin.title ``
341+ and ``roleAdmin.description `` and that's it. But, when dealing with translations,
342+ you could think of multiple approaches. One of them consists of returning the
343+ translation identifier. But this approach has significant drawbacks:
344+
345+ #. It's hard to pass along translation parameters and translation domain if needed.
346+ Like contextualizing a translation with plural, feminine or anything else.
347+
348+ #. The :ref: `extractor command <extracting-translation-contents >`
349+ will not be able to update translation files for you. And loose
350+ the ability to use the ``--clean `` parameter to remove unused
351+ translation identifiers.
328352
329- Templates are now much simpler because you can pass translatable objects to the
330- ``trans `` filter:
353+ That's why you should use "translatable objects", which implements the
354+ :class: `Symfony\\ Contracts\\ Translation\\ TranslatableInterface `.
355+ This object has the responsibility to store all the information needed to fully
356+ translate its contents.
357+
358+ Our updated ``UserRoleEnum::getTitle() `` and ``UserRoleEnum::getDescription() `` functions
359+ return a :class: `Symfony\\ Component\\ Translation\\ TranslatableMessage ` that will hold
360+ the translation identifier::
361+
362+ .. code-block :: php
363+
364+ public function getTitle(): TranslatableMessage
365+ {
366+ return match ($this) {
367+ self::USER => new TranslatableMessage('enums.user_role.user.title'),
368+ self::ADMIN => new TranslatableMessage('enums.user_role.admin.title'),
369+ };
370+ }
371+
372+ public function getDescription(): TranslatableMessage
373+ {
374+ return match ($this) {
375+ self::USER => new TranslatableMessage('enums.user_role.user.description'),
376+ self::ADMIN => new TranslatableMessage('enums.user_role.admin.description'),
377+ };
378+ }
379+
380+ The :ref: `extractor command <extracting-translation-contents >` is now able to keep track
381+ of translation identifiers passed as parameter to the constructor of
382+ :class: `Symfony\\ Component\\ Translation\\ TranslatableMessage ` objects.
383+ And in Twig templates a little change happen by adding the ``trans `` filter:
331384
332385.. code-block :: html+twig
333386
334- <h1>{{ message |trans }}</h1>
335- <p>{{ status |trans }}</p>
387+ <h1>{{ roleAdmin.title |trans }}</h1>
388+ <p>{{ roleAdmin.description |trans }}</p>
336389
337390.. tip ::
338391
339392 The translation parameters can also be a :class: `Symfony\\ Component\\ Translation\\ TranslatableMessage `.
340393
341394.. tip ::
342395
343- There's also a :ref: `function called t() <reference-twig-function-t >`,
396+ There is a :ref: `function called t() <reference-twig-function-t >`,
344397 available both in Twig and PHP, as a shortcut to create translatable objects.
345398
346399.. _translation-in-templates :
@@ -509,6 +562,8 @@ use for translation::
509562
510563 $translator->trans('Symfony is great', locale: 'fr_FR');
511564
565+ .. _extracting-translation-contents :
566+
512567Extracting Translation Contents and Updating Catalogs Automatically
513568-------------------------------------------------------------------
514569
0 commit comments