New in Symfony 5.2: Translatable objects

Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Contributed by
Nate Wiebe
in #37670.
Translating contents usually require more information than the original message, such as the translation parameters and the translation domain. In order to make templates simpler, you could translate the entire messages in the backend and pass the translations to the templates.
However, this is sometimes cumbersome and also requires injecting the translator service in several layers of your application. Another alternative is to pass all the translation data (message, parameters, domain) to the template:
1 2 3 4 5 6 7
return $this->render('...', [
'order_status' => [
'message' => 'order.status_message',
'params' => ['%status%' => $order->getStatus(), '%order_id%' => $order->getId()],
'domain' => 'admin',
],
]);
This no longer requires injecting the translator, but makes templates more complex:
1
{{ order_status.message|trans(order_status.params, order_status.domain) }}
In Symfony 5.2 we're introducing a new TranslatableMessage
class that solves this
problem in an easier way. First, create a TranslatableMessage
object and pass all
the translation data to it:
1 2 3 4 5 6 7 8 9
use Symfony\Component\Translation\TranslatableMessage;
return $this->render('...', [
'order_status' => new TranslatableMessage(
'order.status_message',
['%status%' => $order->getStatus(), '%order_id%' => $order->getId()],
'admin'
),
]);
Now you can translate this object in your template with the same trans
filter as before, but in a much simpler way:
1
{{ order_status|trans }}
The translatable message holds all the translation data, so the trans
filter
can extract it automatically. This solution allows to simplify both the templates
and the backend code, because you don't need to inject the translator or mock it
when writing unit tests.
This feature also introduces a new t()
function, usable both in PHP and Twig
templates, to quickly create this kind of objects. The following example uses
that function to create a fallback translation which uses different parameters
than the default translation:
1 2 3 4 5
{# Before #}
{{ message is defined ? message|trans : fallback|trans({'%param%': value}) }}
{# After #}
{{ message|default(t(fallback, {'%param%': value}))|trans }}
Kudos to the amazing folks at Symfony Slack chat who helped me better understand this feature so I could prepare this blog post.
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments







Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.