Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Translations and languages

For a site to work in several languages, interface texts are not written directly in views but passed through a translation function. It looks the string up in the translation file of the current language. This area is called i18n, short for internationalization.

The application language

Two languages are set in config/web.php:

// config/web.php
$config = [
    'sourceLanguage' => 'en-US',
    'language' => 'de-DE',
    // ...
];

sourceLanguage is the language the strings are written in inside the code (English by default), language is the language they must be translated into. Messages of the framework itself, such as form errors and button labels, become German after that.

The translation function

In views text is wrapped in Yii::t():

<?php
// views/post/index.php
?>
 
<h1><?= Yii::t('app', 'Posts') ?></h1>

The first argument is the category, that is the name of the translation file; app is the convention for your own texts. The second is the source string. Until there is a translation, the page keeps showing "Posts".

The translation file

Translations live in the messages folder, in a subfolder with the language code. Create messages/de-DE/app.php by hand:

// messages/de-DE/app.php
return [
    'Posts' => 'Artikel',
    'Read more' => 'Weiterlesen',
    'Hello, {name}!' => 'Hallo, {name}!',
];

Refresh the page and the heading becomes "Artikel". The app category and the messages folder work in the standard project without extra configuration.

Inserting values

The changing parts of a string are written in curly braces and passed as the third argument:

echo Yii::t('app', 'Hello, {name}!', ['name' => 'Anna']);

The result is "Hallo, Anna!". A translator can move the placeholder as the language requires.

Switching the language

The language can be changed for every request, for example by the visitor's choice stored in the session. The property is set before the page is rendered:

Yii::$app->language = Yii::$app->session->get('language', 'en-US');

A convenient place for this line is the beforeAction() method of a common base controller. The choice is saved by a separate action that writes the language code to the session.

Dates and numbers

The formatter component prints dates and numbers by the rules of the current language:

echo Yii::$app->formatter->asDate($post->created_at, 'long');   // 2. März 2026
echo Yii::$app->formatter->asDecimal(1234.5, 2);                // 1.234,50
echo Yii::$app->formatter->asCurrency(19.99, 'EUR');            // 19,99 €

For English the same calls give "March 2, 2026" and "1,234.50". This formatting requires the intl PHP extension to be enabled.

Your own categories

Other category names are attached in the i18n component:

// config/web.php
'components' => [
    'i18n' => [
        'translations' => [
            'shop*' => [
                'class' => 'yii\i18n\PhpMessageSource',
                'basePath' => '@app/messages',
            ],
        ],
    ],
],

The call Yii::t('shop', 'Cart') will look for a translation in the file messages/de-DE/shop.php.

Common mistake

A string must not be assembled from parts: Yii::t('app', 'Hello, ') . $name leaves the translator no way to change the word order, and the key 'Hello, ' with a trailing space is easy to miss in the file. Pass a whole phrase with placeholders in curly braces to Yii::t().

Thanks for reading!

Donate to the site — we work hard for you.