switch url rules based on app language

First off, a few details.

Don`t use this if you intend to have "language" as a dynamic property.

This is intended for those applications that would be hosted on different servers in different countries. You would copy the code, change the language setting and be done with it.

[i][b]

Also note that this is only going to work if you are making user of the createUrl,createAbsoluteUrl functionality that comes with the framework

[/b][/i]

Right, now code. (But before, one more thing, I love how easy it was for me to implement this. Yii feels like a well setup machine. Good job, good job, good job).

1. Extend webApplication.

Create a file under protected/components/. Let`s call it myapp.php

Inside the file add the base skeleton for the app:




<?php

class myapp extends CWebApplication

{

}

?>



Now let`s go to %webapp_root%/index.php to make some changes so that the website knows to use the application component we just created.

Replace:




Yii::createWebApplication($config)->run();



With:




/*setPathOfAlias('application',config.basepath) is set in CApplication under __construct so we need to set it now, we don't have it set yet. It is set to the same value so don`t worry about it*/

	Yii::setPathOfAlias('application',dirname(__FILE__).DIRECTORY_SEPARATOR.'protected');

/*tell the framework where to find our new application file*/

	Yii::import('application.components.myapp');

/*create application. [i]createWebApplication[/i] is actually calling [i]createApplication[/i] (with different parameters) so we're all good.*/

	Yii::createApplication('myapp',$config)->run();



2. back to your application file (protected/components/myapp.php)

Add:




public function configure($config)

{

	if(is_array($config))

	{

		parent::configure($config);	

		$components = array();

		$this->setComponents($components,true);

	}

}



This function is called by the CApplication constructor and it takes care of saving the config-file data to the application object. What we are doing is to override it. At the moment it does nothing really, but we’ll modify it in a bit.

3. get urlManager config

Go to /protected/config/main.php.

Search for the urlManager array-key.

Copy the urlManager array element to the clipboard, we’ll use it in a moment, then comment it out (the urlManager array element)

4.add urlManager to application configure function

Back to the extended application file.

Paste the urlManager array element that you just copied $components = array(RIGHT HERE);

It should look something like this




$components = array(

	'urlManager'=>array(

		'urlFormat'=>'path'

		,'showScriptName'=>false

		,'caseSensitive'=>false 

		,'urlSuffix'=>'.html'

		,'useStrictParsing'=>true

		,'rules'=>array(

			"<controller:\w+>/<action:\w+>"=>"<controller>/<action>"

		)

	)

);



5. Urlrules file.

At the moment all we have achived is to move the urlManager configuration from the config file to the application file. We need to make it select different rules based on language.

For that we need to replace the ‘rules’ array with a file containing a switch

Create a file under protected/config called urlrules.php

Inside urlrules.php add




switch(strtolower(Yii::app()->getLanguage()))

{

	case 'en_us':

	break

}



Copy, to the clipboard, the value of




	myapp.php->configure()->$components['urlManager']['rules'] 



Paste it under urlrules.php->switch()->case(‘en_us’). It will look something like this




switch(strtolower(Yii::app()->getLanguage()))

{

	case 'en_us':

		return array(

			"<controller:\w+>/<action:\w+>"=>"<controller>/<action>"

		);

	break;

}



(Don`t forget to add return. see above)

Replace the value of




	myapp.php->configure()->$components['urlManager']['rules'] 



With




	require(Yii::getPathOfAlias('application').'/config/urlrules.php')



  1. Finally , add any number of languages you want to the urlrules file

Create a case for each language and change the key value of each rule accordingly. The mapping to controller/action should remain the same.

To modifiy your default language add the “language”=>‘language code here’ conguration option under the main config.

FULL CODE


 


index.php:


............

Yii::setPathOfAlias('application',dirname(__FILE__).DIRECTORY_SEPARATOR.'protected');

Yii::import('application.components.myapp');

Yii::createApplication('myapp',$config)->run();




myapp.php:


<?php

class myapp extends CWebApplication

{	

	public function configure($config)

	{

		if(is_array($config))

		{

			parent::configure($config);

			$components = array(

				'urlManager'=>array(

					'urlFormat'=>'path'

					,'showScriptName'=>false

					,'caseSensitive'=>false 

					,'urlSuffix'=>'.html'

					,'useStrictParsing'=>true

					,'rules'=>require(Yii::getPathOfAlias('application').'/config/urlrules.php')

				)

			);

			$this->setComponents($components,true);

		}

	}

}

?>


main.php:


return array(

	..........

	'language'=>'fr'

	..........

	

	'components'=>array(

		..........

		/*,'urlManager'=>array(

        		'urlFormat'=>'path'

	        	,'showScriptName'=>false

	     		,'caseSensitive'=>false 

     			,'urlSuffix'=>'.html'

     			,'useStrictParsing'=>true

	     		,'rules'=>require('urlrules.php')

	        }*/

		..........

	..........




urlrules.php:


<?php

switch(strtolower(Yii::app()->getLanguage()))

{

	..........

	case 'fr':

		return array( 		

			..........

			"plan_du_site"=>"static/sitemap"

			,"nous_contacter"=>"static/contact"

			,"a_propos"=>"static/about"			

			..........

		);

	break;

	case 'en_us':

		return array( 		

			..........

			,"site_map"=>"static/sitemap"

			,"contact"=>"static/contact"

			,"about_us"=>"static/about"

			..........			

		);		

	break;

	..........

}

?>






P.S. you can obviously use this approach on any config variable that you need set based on other options

Happy Coding

alinmircea