5
votes

I'm using different routing tables for every language, and I have wrote action which change language and redirects to the same page but in target language (and target url).

The main problem is that my action is way too complicated - how can I make it simple? It should change language and redirect to new url (in target language).

In short: We had random valid cake url in one language and we had to translate it to adequate url in another language.

My routing table:

if( 'en' == Configure::read('Config.language') ) {
    Router::connect('/help',   array('controller' => 'pages', 'action' => 'display', 'help') );
} else {
    Router::connect('/pomoc',   array('controller' => 'pages', 'action' => 'display', 'help') );
}

Action changing language:

function lang($lang) {

    // getting previous url table
    $url = $this->referer();
    $url = Router::parse($url);

    // changing language
    if( in_array($lang, Configure::read('Languages.valid') ) ) {
        $this->Session->write('Language', $lang);
        Configure::write('Config.language', $lang);
    }

    // saving base params
    $requestInfo = array(Router::getParams(), Router::getPaths());
    // reload routing table
    Router::reload();
    include(CONFIGS.'routes.php');
    // restore base params
    Router::setRequestInfo($requestInfo);

    // fix for 'pass' params
    if(!empty($url['pass']) && is_array($url['pass'])) {
        $url = array_merge($url, $url['pass']);
        unset($url['pass']);
    }
    $this->redirect($url);
}

About 'pass' key in url table:

/pages/display/help

after Router::parse(), parameter is extracted:

pass => array(
    0 => 'help'
)

and later return value from Router::url() look like that:

/pages/display/pass:Array

so I have to fix it by merging 'pass' value with whole array and removing key

2
Could you give a little more information about what the exact 'flow' is that you desire? As far as I understand you want to be able to have a link on a page (e.g. your help page) which says 'See this page in $language', right? So where do you actually call this lang() action you mention?vindia
It's in the 'select language' box on every pageJacek Kaniuk

2 Answers

0
votes

I have my routes.php like this

Configure::write('Config.language', $_SESSION['lang']);
Router::connect(__('/help',true),   array('controller' => 'pages', 'action' => 'display', 'help') );

so I use the __() to translate the url. It seaches the translation in the po files. And in your lang() function, after changing the Session to the current lang, all you need to do is:

$this->redirect(__('/help'));

Hope this helps

0
votes

I know it is too late to answer that, but for those who experience the similar needs:

In routes.php p1 identifies the static page (same for all languages), could be any string that uniquely identifies the page.

Router::connect('/:language/p1/:translation',   array(
    'controller' => 'pages',
    'action' => 'display',
    'help',
    'options' => array('language' => '[a-zA-Z]{2}')
) );

In your view

$this->Html->link('Click me', array(
    'language'    => Configure::read('Config.language'),
    'controller'  => 'pages',
    'action'      => 'display',
    'help',
    'translation' => __('help') // could be any string in fact
));

will generate link to /en/p1/help in English, else to /xx/p1/pomoc.

Injection of language parameter into every link could be done in AppHelper::url() instead of providing it in every link occurence.

If you want to redirect in controller:

$this->redirect(array(
    'language'    => Configure::read('Config.language'),
    'controller'  => 'pages',
    'action'      => 'display',
    'help',
    'translation' => __('help')
));