Yii 1.1: How to have truly multilingual URLs

3 followers

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:

  • http://www.oligalma.com/en/tutorials (English)
  • http://www.oligalma.com/es/tutorials (Spanish)
  • http://www.oligalma.com/en/services (English)
  • http://www.oligalma.com/es/services (Spanish)

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

  • http://www.oligalma.com/en/tutorials (English)
  • http://www.oligalma.com/es/tutoriales (Spanish)
  • http://www.oligalma.com/en/services (English)
  • http://www.oligalma.com/es/servicios (Spanish)

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.)

Total 1 comment

#19604 report it
rob006 at 2015/09/30 08:20am
defaultPrams

You can use defaultParams instead of matchValue. Then you can create more clean urls:

'juegos'=> array('site/games', 'defaultParams' => array('lang' => 'es')),
'games'=> array('site/games', 'defaultParams' => array('lang' => 'en')),
'contacto'=> array('site/contact', 'defaultParams' => array('lang' => 'es')),
'contact'=> array('site/contact', 'defaultParams' => array('lang' => 'en')),
http://myweb.com/games (English)
http://myweb.com/juegos (Spanish)
http://myweb.com/contact (English)
http://myweb.com/contacto (Spanish)

Leave a comment

Please to leave your comment.

Write new article