Skip to main content
Drupal is a registered trademark of Dries Buytaert
Release: OpenID Connect / OAuth client 3.0.0-alpha9 New alpha version released for module openid_connect (3.0.0-alpha9). Usage Milestone: Google Analytics Module google_analytics crossed 1,000 active installs. Release: Timelinr 1.0.1 Minor update available for module timelinr (1.0.1). Release: GraphQL Compose Codegen 1.1.2 Minor update available for module graphql_compose_codegen (1.1.2). Release: Mapy.com 1.1.3 Minor update available for module mapycom (1.1.3). Release: Ckeditor5 entity browser 3.0.3 Minor update available for module ckeditor5_entity_browser (3.0.3). Release: Ckeditor5 entity browser 3.0.1 Minor update available for module ckeditor5_entity_browser (3.0.1). Release: Ckeditor5 entity browser 3.0.2 Minor update available for module ckeditor5_entity_browser (3.0.2). Release: Teamleader Integration 4.0.2 Minor update available for module teamleader (4.0.2). Module Revived: Entityqueue Buttons 1.1.2 Module entityqueue_buttons updated after 8 months of inactivity (1.1.2).

Symfony Translation

34 sites Security covered Drupal 9–11
View on drupal.org

This project integrates the Symfony Translation component to translate text within your Drupal site. It allows you to translate static messages, use keyword identifiers for easier management, and supports complex message formatting including plurals and variables using the ICU MessageFormat syntax. Translations can be utilized in both Twig templates and PHP code.

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.

Depends on

Dependencies of the latest stable release

  • locale Drupal core

Required by

Tracked projects that depend on this one

No tracked projects depend on this one yet.

Activity

Tracked releases
3
Tracked since
Oct 2025
Latest release
3 months ago
Releases (12 mo)
3 ▲ from 0
Maintenance
Active

Release Timeline

Releases

Version Type Core Release date
1.0.4 Stable 9–11 May 28, 2026
1.0.3 Stable 9–11 Apr 7, 2026
1.0.2 Stable 9–11 Oct 6, 2025