How to translate and do the translations the easy way

  1. Set Configuration Parameters (Step 1)
  2. Use Message Labels (Step 2)
  3. Create Translation Files (Step 3)
  4. Modify Yii Framework Translations (Optional)
  5. Modify Yii Framework Code (Optional)
  6. Create Gii Code Generation Templates (Optional)
Introduction

I wanted to keep all the I18N related translations in separate files, so that I would not need to modify the view files or the model files every time I need to update or fix the translations of application's source language.

So I figured out I can do it this way - it is 100% Yii compatible.

Set Configuration Parameters (Step 1)

First set the value of sourceLanguage parameter to 2 zeroes. Numbers are not allowed in ISO language codes, so they make excellent use as null values. Then set the value of language parameter to your default language.

For example, I use en as default language.

In the file protected/config/main.cfg:

'sourceLanguage'=>'00',
'language'=>'en',

A good idea is to implement application's language management in a base controller, overriding init() method. Language must be set on every controller's execution, or else application's multilingual features do not work as expected.

Another idea is to create and configure a language management behavior for your application.

Use Message Labels (Step 2)

Now you can call and write all Yii::t() functions with message labels, instead of meaningful text.

For example, I have a model Person with a last_name attribute, and I modify attributeLabels() method.

In the file protected/models/Person.php:

public function attributeLabels {
    return array(
        'last_name'=>Yii::t('app','model.person.last_name'),
    );
}

Create Translation Files (Step 3)

Now create message file app.php in all language folders that you are going to use.

For example, I use en, fr, de languages and I need to create the following files:

protected/messages/de/app.php
protected/messages/en/app.php
protected/messages/fr/app.php

And in all of those files you need to write the translated messages labels.

In the file protected/messages/en/app.php:

'model.person.last_name' => 'Last name',

In the file protected/messages/fr/app.php:

'model.person.last_name' => 'Nom de famille',

In the file protected/messages/de/app.php:

'model.person.last_name' => 'Nachname',

Modify Yii Framework Translations (Optional)

Optionally, if you want to modify framework's translations, you can configure application's coreMessages component to set basePath to null. This way the framework searches for translation files in protected/messages folder.

In the file protected/config/main.php:

'coreMessages'=>array(
	'basePath'=>null,
),

Now you can, for example, copy framework/messages/de/yii.php and framework/messages/de/zii.php files to protected/messages/en, protected/messages/de and protected/messages/fr folders, use some regular expression patterns on those files to replace array values with nulls, and they are ready to use.

Now you can modify the following files to suit your needs:

protected/messages/de/yii.php
protected/messages/de/zii.php
protected/messages/en/yii.php
protected/messages/en/zii.php
protected/messages/fr/yii.php
protected/messages/fr/zii.php

Modify Yii Framework Code (Optional)

Optionally, if you want to make use of empty translation strings, then you can modify translateMessage() method in CMessageSource class to comment out empty string check.

NB! Remember this when you upgrade your Yii distribution!

In the file framework/i18n/CMessageSource.php, line 104 (Yii version 1.1.17):

if(isset($this->_messages[$key][$message]) /*&& $this->_messages[$key][$message]!==''*/)

This is not recommended, unless it is absolutely necessary.

A better way would be to create your own class to handle this case, but since $_messages is a private property you need to reimplement the translateMessage() method.

Create Gii Code Generation Templates (Optional)

You can also create your own code generation templates now.

For example, I use Gii module and I use tmpl1 as my code generation template name.

In the file protected/gii/model/templates/tmpl1/model.php:

public function attributeLabels() {
    return array(
<?php foreach($labels as $name=>$label): ?>
        <?php echo "'$name'=>Yii::t('app','model.$tableName.$name'),\n"; ?>
<?php endforeach; ?>
    );
}
Great Success!

Now you can manage all your translations in one place - under messages folder.

16 2
17 followers
Viewed: 87 386 times
Version: 1.1
Category: How-tos
Written by: Roman Solomatin
Last updated by: Roman Solomatin
Created on: Sep 24, 2011
Last updated: 8 years ago
Update Article

Revisions

View all history