Yii Framework Forum: I18N And Urls - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

I18N And Urls I18n urls before Yii sourceLanguage is set (config)

#1 User is offline   Elecen 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 03-July 11

Posted 21 November 2013 - 12:15 PM

Hey there,

I'm writing some translatable urls. Default choice to translate would be to go through Yii::t(...) but at the point of initialisation (app config) the Yii::t is called before the language is set. According to this, I have two options, either "manually" import the array for my routes and just use the array at that point outside Yii::t and B, create a custom url rule for I18n rules.

Before getting into details about either method, has anyone figured how to do it in a different way? Any ideas?

i.e.
en_us => /search
de => /suche
etc.
0

#2 User is offline   yugene 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 515
  • Joined: 08-August 09

Posted 21 November 2013 - 10:46 PM

Probably you may take some ideas from this wiki article
0

#3 User is offline   Elecen 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 03-July 11

Posted 23 November 2013 - 05:24 AM

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 ;)
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!
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users