Internal program error unable load translation resource

internal program error unable load translation resource

Then Django will make some optimizations so as not to load the internationalization machinery. Internally, inline translations use a gettext() call. To translate a single text document and return the results of that translation directly to your application, use the Amazon Translate real-time. Since lazy loaded modules use a different injector from the rest of your application, you can configure them separately with a different loader/compiler/parser/.

Internal program error unable load translation resource - have

Phrase" width="403" height="355">

i18next displays the correct plural form automatically

✋🏽Heads up » The counter variable must be called , otherwise plural selection won’t work.

📖 Go deeper » i18next also provides generalized selection, which can be used for male/female messages, for example. This is called context, and while it’s outside the scope of this guide, you can check it out in the official docs.

Multiple plurals

While the singular/plural forms work for English, they don’t work for many other languages. A quick glance at the Unicode CLDR Language Plural Rules table reveals that languages vary in the number of plural categories, or forms, they have. So i18next’s and variants aren’t enough to cover Arabic, for example, which often has five plural forms, depending on the word.

i18next allows us to handle multiple plural forms in our translation messages using , , etc., to map messages to plural forms. Let’s demonstrate this by translating our “baskets delivered” message into Arabic.

{ "basket_delivered_0": "لم يتم توصيل سلال", "basket_delivered_1": "تم توصيل سله {{count}}", "basket_delivered_2": "تم توصيل سلتان", "basket_delivered_3": "تم توصيل {{count}} سلال", "basket_delivered_4": "تم توصيل {{count}} سله", "basket_delivered_5": "تم توصيل {{count}} سله" }

Our call to can stay the same:

<p>{t("basket_delivered", { count: 2342 })}</p>

i18next will automatically match the correct Arabic plural form based on the given .

baskets_delivered_0 → count = 0 baskets_delivered_1 → count = 1 baskets_delivered_2 → count = 2 baskets_delivered_3 → count is between 3 and 10, inclusive baskets_delivered_4 → count is between 11 and 100, inclusive baskets_delivered_5 → count > 100

Basket message with pluralization in Arabic  <div><h2>Translations</h2><div>             Edit this page         <div><p>The term

Note

The term locale refers roughly to the user's language and country. It can be any string that your application uses to manage translations and other format differences (e.g. currency format). The ISO 639-1language code, an underscore (), then the ISO 3166-1 alpha-2country code (e.g. for French/France) is recommended.

In this article, you'll learn how to use the Translation component in the Symfony Framework. You can read the Translation component documentation to learn even more. Overall, the process has several steps:

  1. Enable and configure Symfony's translation service;
  2. Abstract strings (i.e. "messages") by wrapping them in calls to the ("Translations");
  3. Create translation resources/files for each supported locale that translate each message in the application;
  4. Determine, set and manage the user's locale for the request and optionally on the user's entire session.

Installation

First, run this command to install the translator before using it:

Configuration

The previous command creates an initial config file where you can define the default locale of the app and the fallback locales that will be used if Symfony can't find some translation:

The locale used in translations is the one stored on the request. This is typically set via a attribute on your routes (see How to Work with the User's Locale).

Basic Translation

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

When this code is executed, Symfony will attempt to translate the message "Symfony is great" based on the 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, XLIFF being the recommended format:

For information on where these files should be located, see Translations.

Now, if the language of the user's locale is French (e.g. or ), the message will be translated into . You can also translate the message inside your `templates <Translations in Templates>`.

The Translation Process

To actually translate the message, Symfony uses the following process when using the method:

  • The of the current user, which is stored on the request is determined;
  • A catalog (e.g. big collection) of translated messages is loaded from translation resources defined for the (e.g. ). Messages from the fallback locale are also loaded and added to the catalog if they don't already exist. The end result is a large "dictionary" of translations. This catalog is cached in production to minimize performance impact.
  • If the message is located in the catalog, the translation is returned. If not, the translator returns the original message.

Message Format

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

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:

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.

4.2

Support for ICU MessageFormat was introduced in Symfony 4.2. Prior to this, pluralization was managed by the transChoice() method.

Translations in Templates

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

Read Using Translation in Templates for more information about the Twig tags and filters for translation.

Extracting Translation Contents and Updating Catalogs Automatically

The most time-consuming tasks when translating an application is to extract all the template contents to be translated and to keep all the translation files in sync. Symfony includes a command called that helps you with these tasks:

Note

If you want to see the missing translation strings without actually updating the translation files, remove the option from the command above.

Tip

If you need to extract translation strings from other sources, such as controllers, forms and flash messages, consider using the more advanced third-party TranslationBundle.

Translation Resource/File Names and Locations

Symfony looks for message files (i.e. translations) in the following default locations:

  1. the directory (at the root of the project);
  2. the directory;
  3. the directory inside of any bundle.

4.2

Using the directory to store translations was deprecated in Symfony 4.2. Use instead the directory defined in the option (which is by default).

The locations are listed here with the highest priority first. That is, you can override the translation messages of a bundle in any of the top two directories.

The override mechanism works at a key level: only the overridden keys need to be listed in a higher priority message file. When a key is not found in a message file, the translator will automatically fall back to the lower priority message files.

The filename of the translation files is also important: each message file must be named according to the following path: :

  • domain: An optional way to organize messages into groups (e.g. , or the default ) - see The Translation Component;
  • locale: The locale that the translations are for (e.g. , , etc);
  • loader: How Symfony should load and parse the file (e.g. , , , etc).

The loader can be the name of any registered loader. By default, Symfony provides many loaders, including:

  • : XLIFF file;
  • : PHP file;
  • : YAML file.

The choice of which loader to use is entirely up to you and is a matter of taste. The recommended option is to use for translations. For more options, see The Translation Component.

Note

You can add other directories with the paths option in the configuration:

Caution

Each time you create a new translation resource (or install a bundle that includes a translation resource), be sure to clear your cache so that Symfony can discover the new translation resources:

Fallback Translation Locales

Imagine that the user's locale is and that you're translating the key . To find the French translation, Symfony actually checks translation resources for several locales:

  1. First, Symfony looks for the translation in a translation resource (e.g. );
  2. If it wasn't found, Symfony looks for the translation in a translation resource (e.g. );
  3. If the translation still isn't found, Symfony uses the configuration parameter, which defaults to (see Configuration).

Summary

With the Symfony Translation component, creating an internationalized application no longer needs to be a painful process and boils down to these steps:

  • Abstract messages in your application by wrapping each in the trans() method;
  • Translate each message into multiple locales by creating translation message files. Symfony discovers and processes each file because its name follows a specific convention;
  • Manage the user's locale, which is stored on the request, but can also be set on the user's session.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.