1

I finally have my multilingual CakePHP 2.1 app almost working.

First, I define the default language at the end of core.php:

/* Define default language */
Configure::write('Config.language', 'eng');

Here is my code in AppControler.php:

public function beforeFilter() {
parent::beforeFilter();
    $this->_setLanguage();
    //Configure::write('Config.language', 'fre'); //Manually change the language to test .po file
    $this->Auth->allow('index','view','home','display','logout');
}

function _setLanguage() {

    if ($this->Cookie->read('lang') && !$this->Session->check('Config.language')) {
        $this->Session->write('Config.language', $this->Cookie->read('lang'));
    }
    else if (isset($this->params['language']) && ($this->params['language']
             !=  $this->Session->read('Config.language'))) {

        $this->Session->write('Config.language', $this->params['language']);
        $this->Cookie->write('lang', $this->params['language'], false, '20 days');
    }
}

If I uncomment Configure::write('Config.language', 'fre'); in AppController.php, the whole site is in French (except database driven content, for which I plan to use TranslateBehavior). However, I want to use URL-based language switching on a button click, and that's where the app breaks down. Here is my route, based on this nuts-and-bolts tutorial:

Router::connect('/:language/:controller/:action/*', array(), array('language' => '[a-z]{2}'));

Here is my button code:

<?php echo $this->Html->link($this->Html->image('../img/PUZ013-US-Flag.png', array('border' => '0')),array('language'=>'eng'),array('target' => '_parent', 'escape' => false));;?>&nbsp <?php echo $this->Html->link($this->Html->image('../img/PUZ013-FR-Flag.png', array('border' => '0')),array('language'=>'fre'),array('target' => '_parent', 'escape' => false));?>

I have this in AppHelper to handle the URL switching, but it's not working. The URL should be example.com/fre/controller/action, but instead it is example.com/controller/action/language:fre, and the cookie is not changing.

class AppHelper extends Helper {

  public function url($url = null, $full = false) {
        if(!isset($url['language']) && isset($this->params['language'])) {
          $url['language'] = $this->params['language'];
        }

        return parent::url($url, $full);
   }

}

If you click on the flags, nothing happens. What am I missing?

3 Answers 3

1

Can you give us the HTML output of the flags ?

I think it's an issue with your url method in your AppHelper. If you try to echo something in it, does it show ?

Edit : I've another explanation, in your route, you have :

'language' => '[a-z]{2}'

As your language code use 3 characters, you should use :

'language' => '[a-z]{3}'
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, that helped! The 'fre' is loading where it should now, but it's checking for FreController instead of seeing the fre as the language parameter.
1

I ended up adding a function to my AppController and calling it in my beforeFilter():

My beforeFilter() looks like this:

public function beforeFilter() {
    parent::beforeFilter();
    $this->_checkRoute();
    $this->Auth->allow('index','view','home','display','logout');
}

Here is the _checkRoute() function:

function _checkRoute() {
        $params = $this->params['pass'];
        $url = $this->here;

        if (strpos($url, 'language:fre')) {
            $this->Session->write('Config.language', 'fre'); 
            Configure::write('Config.language', 'fre');
        }

        elseif (strpos($url, 'language:eng')) {
            Configure::write('Config.language', 'eng');
            $this->Session->write('Config.language', 'eng');
        }

}

When a user clicks the language icon button, the individual page is translated. The only remaining issue is that the session unsets when the user clicks on a menu link, as the URL parameter is not maintained. Another puzzle for another day.

Comments

0

Just in case others fall over this question. What I did was using deewilcox's answer above and changed the code a bit.

function _checkRoute() {
    $lang = $this->params["language"];


    if ($lang != $this->Session->read("Config.language")) {
        $this->Session->write('Config.language', "".$lang);
        Configure::write('Config.language', "".$lang);
    }
}

I used the routing as in the question, but I also use custom routing. The custom routing has to be written before

Router::connect('/:language/:controller/:action/*', array(), array('language' => '[a-z]{3}')); 

if you use

$this->Html->link()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.