I have created a multilingual application in CakePHP 2 I want to include some static content in different languages and I'm having trouble setting up the routing.
I have it working for language/controller/action
type routes but if I want to have static content how do I route the PagesController to views in View/Pages/membership.ctp
for the default language English and View/fr/Pages/abonnement.ctp
for the french translation so that the url will be just /membership or /fr/abonnement? And what is the best way to relate the translations to each other so the language switching links will work and reverse routing will work properly?
I have the following routes already
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/:language',
array('controller' => 'pages', 'action' => 'display', 'home'),
array('language' => 'en|fr', 'persist'=>array('language')));
Router::connect('/:language/:controller',
array('action' => 'index'),
array('language' => 'en|fr', 'persist'=>array('language')));
Router::connect('/:language/:controller/:action/*',
array(),
array('language' => 'en|fr', 'persist'=>array('language')));
the _setLanguage()
method called from AppController's beforeFilter()
protected function _setLanguage() {
//if the cookie was previously set, and Config.language has not been set
//write the Config.language with the value from the Cookie
if ($this->Cookie->read('lang') && !$this->Session->check('Config.language')) {
$this->Session->write('Config.language', $this->Cookie->read('lang'));
}
//if the user clicked the language URL
else if ( isset($this->params['language']) && ($this->params['language'] != $this->Session->read('Config.language'))) {
// get the correct language code
$languageCodeEquivalencies = array(
'fr'=>'fra',
'en'=>'eng'
);
$languageCode = $this->params['language'];
if(in_array($languageCode, array_keys($languageCodeEquivalencies))) {
$languageCode = $languageCodeEquivalencies[$languageCode];
}
//then update the value in Session and the one in Cookie
$this->Session->write('Config.language', $languageCode);
$this->Cookie->write('lang', $languageCode, false, '20 days');
}
//ensure that both I18n and TranslateBehavior access the same language value.
if ($this->Session->check('Config.language')) {
Configure::write('Config.language', $this->Session->read('Config.language'));
}
}
and my language switching links look like this
if($this->Session->read('Config.language') == 'fra'):
echo $this->Html->link('English', array_merge(array('language'=>'en'), $this->passedArgs));
else:
echo $this->Html->link('Français', array_merge(array('language'=>'fr'), $this->passedArgs));
endif;
Here's what I added to get it working...
Controller/AppController.php
public function beforeFilter() {
...
// render language specific view if it exists
$locale = Configure::read('Config.language');
if ($locale && file_exists(APP . 'View' . DS . $locale . DS . $this->viewPath)) {
// e.g. use /app/View/fra/Pages/tos.ctp instead of /app/View/Pages/tos.ctp
$this->viewPath = $locale . DS . $this->viewPath;
}
...
}
Config/routes.php
Router::connect('/fr/abonnement', array('language'=>'fr', 'controller' => 'pages', 'action' => 'display', 'membership'));
Router::connect('/en/membership', array('language'=>'en', 'controller' => 'pages', 'action' => 'display', 'membership'));
Which is working fine right now as I have a limited number of static pages and I only need to support two languages. I'm pretty sure manually setting up the routes for each language and static page will become too unwieldy after a decent number of pages. Let me know if you think of a better solution.