Eventually I did the following to have translatable urls with full support of the CUrlRule expressions
Step1.
Yii Bootstrap - I override the createComponent function. The create component is very nicely written but, since we know for sure variables with the name $0, $1, etc are not allowed, I modified it to treat integer keys as arguments it needs to pass to the constructor (to overcome the issue with how CUrlManager instantiates the CUrlRule
<?php
// Adjust the path to your YiiBase according to your Yii folder structure - mine is modified <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/wink.gif' class='bbc_emoticon' alt=';)' />
require(dirname(__FILE__).'/../../yii/YiiBase.php');
class Yii extends YiiBase
{
public static function createComponent($config)
{
if(is_string($config))
{
$type=$config;
$config=array();
}
elseif(isset($config['class']))
{
$type=$config['class'];
unset($config['class']);
}
else
throw new CException(Yii::t('yii','Object configuration must be an array containing a "class" element.'));
if(!class_exists($type,false))
$type=Yii::import($type,true);
if(($n=func_num_args())>1)
{
$args=func_get_args();
if($n===2)
$object=new $type($args[1]);
elseif($n===3)
$object=new $type($args[1],$args[2]);
elseif($n===4)
$object=new $type($args[1],$args[2],$args[3]);
else
{
unset($args[0]);
$class=new ReflectionClass($type);
// Note: ReflectionClass::newInstanceArgs() is available for PHP 5.1.3+
// $object=$class->newInstanceArgs($args);
$object=call_user_func_array(array($class,'newInstance'),$args);
}
}
else
{
// This is the code I added to it. The rest is the original createComponent function replacing the $object=new $type;
$args=array();
foreach($config as $k => $v)
if (is_int($k)) {
$args[] = $v;
unset($config[$k]);
}
$n = count($args);
if ($n===0)
$object=new $type;
elseif ($n===1)
$object = new $type($args[0]);
elseif($n===2)
$object = new $type($args[0], $args[1]);
elseif($n===3)
$object = new $type($args[0], $args[1], $args[2]);
}
// My code ends here
foreach($config as $key=>$value)
$object->$key=$value;
return $object;
}
}
Step 2.
The above modification allowed me to actually extend the CUrlRule and create the LocalisedUrlRule
<?php
class LocalisedUrlRule extends CUrlRule {
public function __construct($pattern, $route) {
parent::__construct($route, Yii::t('routes', $pattern));
}
}
Step 3.
So, in my config I could generate urls like this
'urlManager'=>array(
'rules'=>array(
// Dedicated urls - SEO friendly front-end (localised)
// FYI: translation here takes place just to have the script generate the translation string automatically. At this point the Yii::t will always return the original text (i.e. /contact) regardless the language setting
array('class' => 'LocalisedUrlRule', Yii::t('routes', '/contact'), '/contact/index'),
),
),
The above is sufficient for the parseUrl functionality. The createUrl is not tested yet and not sure if it’s going to work perfectly.
Comments and ideas are always welcomed!