Yii 1.1: Setting and maintaining the language in Application (i18n)

32 followers

As seen in this post, Yii doesn't enforce how language is set and maintained within the session.

According to that post, the preferred method is to create a base controller which implements code for maintaining the language state. That Controller is then used in your code instead of CControler (by defing your classes with "class ... extends MyController")

Here's my method of implementing this idea:

components/MyController.php

<?php
class MyController extends CController
{
    function init()
    {
        parent::init();
        $app = Yii::app();
        if (isset($_POST['_lang']))
        {
            $app->language = $_POST['_lang'];
            $app->session['_lang'] = $app->language;
        }
        else if (isset($app->session['_lang']))
        {
            $app->language = $app->session['_lang'];
        }
    }
}
?>

You can use a custom made Widget to let the user select language:

components/LangBox.php

<?php
class LangBox extends CWidget
{
    public function run()
    {
        $currentLang = Yii::app()->language;
        $this->render('langBox', array('currentLang' => $currentLang));
    }
}
?>

components/views/langBox.php

<?php echo CHtml::form(); ?>
    <div id="langdrop">
        <?php echo CHtml::dropDownList('_lang', $currentLang, array(
            'en_us' => 'English', 'is_is' => 'Icelandic'), array('submit' => '')); ?>
    </div>
<?php echo CHtml::endForm(); ?>

See also ΒΆ

  • Here is another approach using behaviors.

Total 12 comments

#18731 report it
black-room-boy at 2014/12/18 01:10pm
Language in URL

How do you store language in URL ? For example "example.com/de/site/index" ?

#15167 report it
zaccaria at 2013/10/14 07:03am
re Narender Negi
#15166 report it
Narender Negi at 2013/10/14 06:59am
translation using database

Hi,

How can we implement translation using database.I want to give translation option to my site and when someclick on french then action translate the english value by fetching its french translated value from database.

Thanks

#8731 report it
Patrice at 2012/06/22 05:05am
Thanks

Thanks for this wiki, very helpful. In addition, I defaulted the language with the preferred language (= first value coming from the HTTP_ACCEPT_LANGUAGE element) :

if (isset($_POST['_lang']))
        {
            $app->language = $_POST['_lang'];
            $app->session['_lang'] = $app->language;
        }
        else if (isset($app->session['_lang']))
        {
            $app->language = $app->session['_lang'];
        }
        else
        {
// 'fr_FR' becomes 'fr'
            $app->language = substr(Yii::app()->getRequest()->getPreferredLanguage(),0,2);
            $app->session['_lang'] = substr(Yii::app()->getRequest()->getPreferredLanguage(),0,2);
        }
#4647 report it
Kiriakos Kappa Krastillis at 2011/07/29 10:31am
elaborate version

I use a more elaborate version of the code posted here to also do stuff like language validation etc. The concept is still a model/component/behavior bundle

private function setLanguage(){
 
        if (isset( $_POST['_lang']) && $this->validateLang( $_POST['_lang'] )){
            $this->setDisplayedLangProperties( $_POST['_lang'] );
            Yii::app()->request->redirect( Menu::model()->getLangDefaultMenu()->menuUrl );
           // the previous line is only needed in cases where the content displayed can only be displayed in one language.
 
        }elseif( Yii::app()->user->getState('displayedLanguage') === null ){
            $this->setDisplayedLangProperties( 'en' );
            // if no language has been set set the default language
        }elseif( Yii::app()->user->getState('displayedLanguage') !== null ){
            $this->setDisplayedLangProperties(
                    Yii::app()->user->getState('displayedLanguage')->iso2 );
            // in case the language is already set and no change is needed just keep the settings alive
        }
    }

validateLang() is just a function that returns true if the passed argument is a valid language tag. setDisplayedLangProperties just gets a lang model and sets it as a user state, this way everything in the application can get a refference to the displayed language model and use it ( because some times the two char iso code just isnt enough )

#4502 report it
Kiriakos Kappa Krastillis at 2011/07/14 04:11am
Original post

the original forum post isn't available anymore.

#3456 report it
zaccaria at 2011/04/14 02:48am
re: user session and behaviour

After re-reading this wiki, I advice anyone to use a mixed approach:

Use behavior instead of init of the model, but use the method displayed in the article (reading the input directly in the onInit) instead of following my example of another action.

This approach is quite better than mine.

If anyone will do this "mixed approach" with success and test it, can please update the article with a definitive, tested, version?

#2736 report it
WallTearer at 2011/02/03 10:03am
Behavior

Just for other folks, who maybe was struggling with Yii's documentation too when they were trying to find out how and where to put application behavior. So 1st step is to put file with class ApplicationConfigBehavior to the protected/components directory. And 2nd step is to add to your config in protected/config/main.php

'behaviors' => array('ApplicationConfigBehavior')

Easy, huh? But it took me quite a while to figure this out...

p.s. Thanks to zaccaria for the hint on how to run some piece of code before all requests without overriding controller class.

#1941 report it
zaccaria at 2010/10/18 06:44am
user session and behaviour

You can enhance this language managment.

Is possible to write a behavior for the application that will set the language, without any needs to create a masterclass for all controllers

<?php
 
/**
 * ApplicationConfigBehavior is a behavior for the application.
 * It loads additional config paramenters that cannot be statically 
 * written in config/main
 */
class ApplicationConfigBehavior extends CBehavior
{
    /**
     * Declares events and the event handler methods
     * See yii documentation on behaviour
     */
    public function events()
    {
        return array_merge(parent::events(), array(
            'onBeginRequest'=>'beginRequest',
        ));
    }
 
    /**
     * Load configuration that cannot be put in config/main
     */
    public function beginRequest()
    {
        if ($this->owner->user->getState('applicationLanguage'))
            $this->owner->language=$this->owner->user->getState('applicationLanguage');
        else 
            $this->owner->language='en';
    }
}

As you see, I took the actual language by the user state. For save the language I created a special action in SIteController:

/**
     * set the application language or the theme according to the choice of the user
     */
    public function actionSettings()
    {
        if (isset($_POST['language']))
            Yii::app()->user->setState('applicationLanguage',$_POST['language']);
        $this->redirect($_POST['url']);
    }
#1386 report it
auxbuss at 2009/08/14 06:20pm
why component instead of controller?

Because the file is auto required from /components, whereas it isn't in /controllers

#1387 report it
auxbuss at 2009/08/14 06:18pm
You can simplify quite a lot...
function change_language() {
  if (isset($_POST['lang']))
    Yii::app()->session['lang'] = $_POST['lang'];
  if (isset(Yii::app()->session['lang']))
    Yii::app()->language = Yii::app()->session['lang'];
}
#1578 report it
MetaYii at 2009/06/17 04:33pm
cookies

You could also store the preferred language in a cookie, instead of the session, and then retrieve it on every page load and on the language selection page.

Leave a comment

Please to leave your comment.

Write new article