Url And I18

Hi All,

I’m trying to create a dropdown with two options for two languages, it’s calling an action where I set the language, but I would like to show an URL like this: http://domain.com/es/boo or http://domain.com/en/boo

And keep that structure where the user click on other action.

I have been trying to get this but I think that I’m missing something…

This is the URL Manger:




'urlManager'=>array(

    'urlFormat'=>'path','showScriptName'=>false, 'caseSensitive'=>false,

    'rules'=>array(

        ''=>'site/language',

       '<action>'=>'site/<action>',

    ),

),



Behavior for all requests:




public function beginRequest()

    {

        if (isset($_POST['_lang']))

            $this->owner->user->setState('applicationLanguage', $_POST['_lang']);

		

        if (isset($_GET['_lang']))

            $this->owner->user->setState('applicationLanguage', $_GET['_lang']);

		

        if ($this->owner->user->getState('applicationLanguage')){

            $this->owner->language = $this->owner->user->getState('applicationLanguage');

        }else{

            // 'es_ES' becomes 'es'

                $this->owner->language = substr(Yii::app()->getRequest()->getPreferredLanguage(),0,2);

                //$app->session['_lang'] = substr(Yii::app()->getRequest()->getPreferredLanguage(),0,2);

        }

		

		if (empty($this->owner->language)){

		    $this->owner->language = 'en';

		}

    }



View:




<ul class="nav nav-pills nav-custom pull-right">


    <li class="dropdown">

        <a class="dropdown-toggle" data-toggle="dropdown" href="#"><?php echo strtoupper(Yii::app()->language); ?> <i class="icon-globe"></i></a>

        <ul class="dropdown-menu">

            <li><?php echo CHtml::link('English', Yii::app()->createUrl('/site/language', array('_lang'=>'en'))); ?></li>

            <li><?php echo CHtml::link('Español', Yii::app()->createUrl('/site/language', array('_lang'=>'es'))); ?></li>

        </ul>

    </li>

</ul>



Controller:




public function actionLanguage(){

	    $this->refresh();

	}



Thanks in advance!

Just FYI:

If you create a rule like this


'<lang:(es|en)>/<_c:\w+>/<_a:\w+>' => '<_c>/<_a>',

then the lang code will be available in $_GET.

So you can take it in, say, beforeAction and set app language accordingly.

The thing is, if I open URL like /en/something/something1 I expect to see english version, no matter what lang I have chosen before.

I mean,

/en/something/another == always english version

/es/something/another == always spanish version

/something/another == user-selected version

Clean and simple.

Thanks ORey for your response. Now I understand a bit more abour URL Manager, I see that creating a beforeAction and setting up that rule it works as you say:

But… I thougth that when an user selects a language the url must keep the lang parameter as http://domain.com/en/something1/another1, and if the user clicks in another action the lang parameter must persist http://domain.com/en/something2/another1, am I right?

Another thing, I can’t setup the language when the user clicks in the dropdown item, it should refresh the currect page, but changing the language, right? I have tried by creating an action, but it doesn’t work, any tip is more than welcome.

Controller:




        protected function beforeAction($action){

	    if (isset($_GET['_lang'])){

		    Yii::app()->language = $_GET['_lang'];

		}

		

		if (empty(Yii::app()->language)){

		    Yii::app()->language = 'en';

		}

		return true;

	}

	public function actionLanguage(){

	    $this->refresh();

	}



View:




<ul class="nav nav-pills nav-custom pull-right">


    <li class="dropdown">

        <a class="dropdown-toggle" data-toggle="dropdown" href="#"><?php echo strtoupper(Yii::app()->language); ?> <i class="icon-globe"></i></a>

        <ul class="dropdown-menu">

            <li><?php echo CHtml::link('English', Yii::app()->createUrl('/site/language', array('_lang'=>'en'))); ?></li>

            <li><?php echo CHtml::link('Español', Yii::app()->createUrl('/site/language', array('_lang'=>'es'))); ?></li>

        </ul>

    </li>

</ul>


Thanks in advance!



Seems right. I wonder if there’s a simple way to do this without adding extra param to every createUrl() in Yii1.

First of all, you should check if this language is supported by your translations, something like


if (in_array($lang, array(...list of supported languages))

,

otherwise bad things may happen.

Next, you may also want to look at these guys:

http://www.yiiframework.com/doc/api/1.1/CHttpRequest#preferredLanguage-detail - get user lang

http://www.yiiframework.com/doc/api/1.1/CHttpRequest#getParam-detail - convenient way to retrieve request var or default value.

Speaking about your code, beforeAction should be placed in some base controller (like components/Controller) and all the others should extend it.

Here’s how setting language may look like:


public function actionSetLang($lang = 'en')

{

    if (in_array($lang, Yii::app()->params['installedLanguages'])) {

        Yii::app()->session->set('lang', $lang); // or setState, whatever you like

    } 


    // return $this->redirect(Yii::app()->user->returnUrl);

    return $this->redirect('/');

}

(sorry I may have made a couple of mistakes in this code, but you’ve got the main idea)

HI,

Read this link in Spanish Link.

It works and it is simple and language is always visible in url

Thanks to both, you guys were really helpful. I have to look deeply into those links you provided me. Thanks!