Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Translations

A Magento shop often runs in several languages. So strings in code are not printed directly: they are wrapped in the __() function, and the translation is kept in a separate file. Source strings are written in English by convention — they serve as keys.

Where translations live

A module's translations are in the i18n folder, one CSV file per language. The file name is a language and country code: de_DE.csv, fr_FR.csv. The file is created by hand.

app/code/Acme/Hello/
├── i18n/
│   └── de_DE.csv           new file
└── view/frontend/templates/greeting.phtml

A translatable string

<!-- app/code/Acme/Hello/view/frontend/templates/greeting.phtml -->
<h2><?= $escaper->escapeHtml(__('Hello!')) ?></h2>

The __() function looks up the translation of the string for the language of the current store view. If there is none, the source string is printed — "Hello!".

The translation file

"Hello!","Hallo!"
"Welcome to %1!","Willkommen bei %1!"
"Reviews","Bewertungen"

This is the content of the app/code/Acme/Hello/i18n/de_DE.csv file. Every line has two quoted parts separated by a comma: the source phrase and the translation. The source phrase must match the __() argument to the last character.

Switching the language

The store view language is chosen in the admin panel: Stores → Configuration → General → General → Locale Options, the Locale field. The value can be set separately for each store view.

bin/magento cache:clean

After cleaning the cache the /hello page shows "Hallo!" on the German store view and "Hello!" on the English one.

Placeholders

The changing parts of a phrase are marked with %1, %2 and passed as the following arguments:

// app/code/Acme/Hello/Model/Greeter.php
public function greet(string $name): string
{
    return (string) __('Hello, %1!', $name);
}

In the translation file the placeholders can be reordered: "Hello, %1!","%1, hallo!". The function returns not a string but a phrase object — it turns into text when printed or cast to string.

Strings in XML

Labels from XML files are translated too — add them to the same CSV file:

Where the string isHow it is marked
system.xmlThe translate="label" attribute on a section, a group and a field
menu.xml, acl.xmlThe title attribute is translated automatically
UI componentsThe translate="true" attribute on the label tag

Strings in JavaScript

Scripts use the $t() function from the mage/translate module: $t('Hello!'). Magento gathers translations for it into a separate file together with styles and scripts, so static files must be rebuilt after a translation changes.

Collecting phrases

To avoid writing phrases out by hand, a command collects them:

bin/magento i18n:collect-phrases -o app/code/Acme/Hello/i18n/en_US.csv app/code/Acme/Hello

It scans the module code and creates a file where every phrase is repeated twice. Copy it under the name de_DE.csv and replace the second half of each line with the translation.

Where a translation comes from

SourcePriority
The i18n files of modulesLowest
A language pack installed through ComposerHigher
An i18n file in a theme: app/design/frontend/Acme/simple/i18n/de_DE.csvHigher still
Translations saved in the databaseHighest

Ready-made core translations for many languages are installed as language packs.

Common mistake

A variable or a concatenated string is passed to __(): __('Hello, ' . $name) or __($message). The phrase collector does not find such a string, and a translation cannot be written for every name. Always write a complete constant string in __() and insert the changing parts with %1 placeholders.

Thanks for reading!

Donate to the site — we work hard for you.