Multilanguage and SEO friendly

  1. Configuration
  2. In a view
  3. Add a folder in code directory
  4. Support SEO friendly URLs

Configuration

In your application configuration (protected/config/main.php), set the sourceLanguage parameter to English:

return array(
...
, 'sourceLanguage'=>'en'
...
)

In a view

Use the Yii::t() function to translate strings:

echo Yii::t('codexamples_translator','the quick brown fox jumped over the lazy dog');

echo Yii::t('codexamples_translator','you have {count} new emails', array('{count}'=>5));

echo Yii::t('codexamples_translator','n==1#one book|n>1#many books', array(2));

The return value will default to the English value in the quotes, but if the appropriate translation file is found, then the translated value will be returned. Note the use of {parameters}. You can also format dates and numbers:

echo Yii::app()->dateFormatter->formatDateTime(time());

echo Yii::app()->numberFormatter->formatDecimal(3.14);

Add a folder in code directory

Add a folder "fr" under /protected/messages (if not exist, create /protected/messages/ folder), and a file called "codexamples_translator.php". The content of codexamples_translator.php should be this:

return array(
'the quick brown fox jumped over the lazy dog' => 'le renard marron agile saute par dessus le chien  paresseux'
, 'you have {count} new emails' => 'vous avez {count} nouveaux e-mails'
, 'n==1#one book|n>1#many books '=> 'n==1#un livre|n>1#de nombreux livres'
);

It's an associative array where the first value is the key, and the second value is the translated version. It's easier just to use the English value as the key than to use a numbering system.

Then, you can set the language. This is best done in the beginRequest event handler based on user preferences, but here's how to do it manually:

Yii::app()->language='fr';

Here are the results in 'en':

Ouput "en": ~~~ the quick brown fox jumped over the lazy dog you have 5 new emails many books Dec 17, 2010 11:27:23 PM 3.14 ~~~

Ouput "fr": ~~~ le renard marron agile saute par dessus le chien paresseux vous avez 5 nouveaux e-mails de nombreux livres 17 déc. 2010 23:24:12 3,14 ~~~

Support SEO friendly URLs

In your configuration url manager

add <lang:\w+> to each rule, such as:

'urlManager'=>array(
	'urlFormat'=>'path',
    'showScriptName' => false,
	'rules'=>array(
                '<lang:\w+>/post-<id:\d+>/<title:.*?>' => array('post/view', 'urlSuffix' => '/', 'caseSensitive' => false),
		'<lang:\w+>/<controller:\w+>/<id:\d+>'=>'<controller>/view',
		'<lang:\w+>/<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
		'<lang:\w+>/<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
	),
),
Create frendly url, 2 cases:

Case 1: Simple case

In view, create a link, add lang parameter such as:

//Suppose that $data is post object
echo CHtml::link('post/view',
	array(
		'id'=>$data->id,
		'title'=>$data->title,
		'lang'=>Yii::app()->language
		)
	);

//OR
$model = Post::model()->findByPk(1);
echo CHtml::link('post/view',
	array(
		'id'=>$model->id,
		'title'=>$model->title,
		'lang'=>Yii::app()->language
		)
	);


Case 2: Better solution

If you create a url in model like this solution: in Post.php model, create function called getUrl()

public function getUrl()
{
    return Yii::app()->createUrl('post/view', array(
        'id' => $this->id,
        'title' => $this->title,
        'lang' => Yii::app()->language,
    ));
}

Now, in view, you only call (object) $post->url then it will return a friendly url like this:

Ouput: ~~~ /en/post-1/this-is-test-post/ ~~~

Conclusion, You can also create views specific to a language. Under protected/views/site/, create a 'fr' folder, and add a page index.php . This will be the French index page for the site, and can be entirely different from the English index page if you desire.