How to have truly multilingual URLs

You are viewing revision #27 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version or see the changes made in this revision.

« previous (#26)next (#28) »

  1. Introduction
  2. The problem
  3. The solution

Introduction

We can easily have a multilingual site if we put a "lang" parameter that comes via GET. For example:

<?php 
echo CHtml::link('Tutorials', array('/site/tutorials', 'lang' => 'en')); 
echo CHtml::link('Tutoriales', array('/site/tutorials', 'lang' => 'es')); 
echo CHtml::link('Services', array('/site/services', 'lang' => 'en')); 
echo CHtml::link('Servicios', array('/site/services', 'lang' => 'es')); 
?>

Then, in Controller.php, we need to put this piece of code:

public function beforeAction($action)
{
      if(isset($_GET['lang']))
      {
	      Yii::app()->setLanguage($_GET['lang']);
      }
      else
      {
	      Yii::app()->setLanguage('en');
      }
      
      return true;
}

Finally we can add the following rules:

'urlManager'=>array(
    'urlFormat'=>'path',
    'showScriptName'=>false,
    'rules'=>array(
	    '<lang:\w+>'=>'site/index',
	    '<lang:\w+>/<action>' => 'site/<action>',
     )
),

The problem

This leads to URLs like these:

This is fine to have a multilingual site. But, we can go one step further. What if we want URLs like these:

That is, every URL has its particular path. It changes the whole URL, not just the two initial letters (en/es).

The solution

'urlManager'=>array(
    'matchValue'=>true,
    'urlFormat'=>'path',
    'showScriptName'=>false,
    'rules'=>array(
	       '<lang:\w+>'=>'site/index',
           '<lang:es>/tutoriales'=> 'site/tutorials',
           '<lang:en>/tutorials'=> 'site/tutorials',
           '<lang:es>/servicios'=> 'site/services',
           '<lang:en>/services'=> 'site/services',
	       '<lang:\w+>/<action>' => 'site/<action>',
     )
),

(Take note that we also added 'matchValue' => true to the urlManager array.)