Drupal is a registered trademark of Dries Buytaert
drupal 11.3.7 Update released for Drupal core (11.3.7)! drupal 11.2.11 Update released for Drupal core (11.2.11)! drupal 10.6.7 Update released for Drupal core (10.6.7)! drupal 10.5.9 Update released for Drupal core (10.5.9)! cms 2.1.1 Update released for Drupal core (2.1.1)! drupal 11.3.6 Update released for Drupal core (11.3.6)! drupal 10.6.6 Update released for Drupal core (10.6.6)! cms 2.1.0 Update released for Drupal core (2.1.0)! bootstrap 8.x-3.40 Minor update available for theme bootstrap (8.x-3.40). menu_link_attributes 8.x-1.7 Minor update available for module menu_link_attributes (8.x-1.7). eca 3.1.1 Minor update available for module eca (3.1.1). layout_paragraphs 2.1.3 Minor update available for module layout_paragraphs (2.1.3). ai 1.3.3 Minor update available for module ai (1.3.3). ai 1.2.14 Minor update available for module ai (1.2.14). node_revision_delete 2.0.3 Minor update available for module node_revision_delete (2.0.3). moderated_content_bulk_publish 2.0.52 Minor update available for module moderated_content_bulk_publish (2.0.52). klaro 3.0.10 Minor update available for module klaro (3.0.10). klaro 3.0.9 Minor update available for module klaro (3.0.9). layout_paragraphs 2.1.2 Minor update available for module layout_paragraphs (2.1.2). geofield_map 11.1.8 Minor update available for module geofield_map (11.1.8).

symfony_translation

35 sites Security covered
View on drupal.org

Integrates the Symfony Translation component.

Basic Translation

Translation of text is done through the symfony_translation.translator service (Translator). To translate a block of text (called a message), use the trans() method. Suppose, for example, that you're translating a static message from inside a controller:

// ...
use Symfony\Contracts\Translation\TranslatorInterface;

public function index(TranslatorInterface $translator)
{
    $translated = $translator->trans('Symfony is great');

    // ...
}

When this code is run, Symfony will attempt to translate the message "Symfony is great" based on the locale of the user. For this to work, you need to tell Symfony how to translate the message via a "translation resource", which is usually a file that contains a collection of translations for a given locale. This "dictionary" of translations can be created in several different formats:

# translations/messages.fr.yaml
Symfony is great: J'aime Symfony
// translations/messages.fr.php
return [
    'Symfony is great' => "J'aime Symfony",
];

Now, if the language of the user's locale is French (e.g. fr_FR or fr_BE), the message will be translated into J'aime Symfony.

In places where dependency injection is impossible, you can use the st function instead.

Using Real or Keyword Messages

This example illustrates the two different philosophies when creating messages to be translated:

$translator->trans('Symfony is great');

$translator->trans('symfony.great');

In the first method, messages are written in the language of the default locale (English in this case). That message is then used as the "id" when creating translations.

In the second method, messages are actually "keywords" that convey the idea of the message. The keyword message is then used as the "id" for any translations. In this case, translations must be made for the default locale (i.e. to translate symfony.great to Symfony is great).

The second method is handy because the message key won't need to be changed in every translation file if you decide that the message should actually read "Symfony is really great" in the default locale.

The choice of which method to use is entirely up to you, but the "keyword" format is often recommended for multi-language applications, whereas for shared bundles that contain translation resources we recommend the real message, so your application can choose to disable the translator layer and you will see a readable message.

Additionally, the php and yaml file formats support nested ids to avoid repeating yourself if you use keywords instead of real text for your ids:

symfony:
    is:
        # id is symfony.is.great
        great: Symfony is great
        # id is symfony.is.amazing
        amazing: Symfony is amazing
    has:
        # id is symfony.has.bundles
        bundles: Symfony has bundles
user:
    # id is user.login
    login: Login

Message Format

Sometimes, a message containing a variable needs to be translated:

// ...
$translated = $translator->trans('Hello '.$name);

However, creating a translation for this string is impossible since the translator will try to look up the message including the variable portions (e.g. "Hello Ryan" or "Hello Fabien").

Another complication is when you have translations that may or may not be plural, based on some variable:

There is one apple.
There are 5 apples.

To manage these situations, Symfony follows the ICU MessageFormat syntax by using PHP's MessageFormatter class. Read more about this in How to Translate Messages using the ICU MessageFormat.

Translations in Templates

Most of the time, translation occurs in templates. Symfony provides native support for Twig templates.

The st and strans filters can be used to translate variable texts and complex expressions:

{{ message|st }}

{{ message|strans({'name': 'Fabien'}, 'app') }}

The above documentation was taken from the Symfony documentation and altered where necessary.

Activity

Total releases
2
First release
Oct 2025
Latest release
1 week ago
Release cadence
183 days
Stability
100% stable

Releases

Version Type Release date
1.0.3 Stable Apr 7, 2026
1.0.2 Stable Oct 6, 2025