In this recipe, we will learn how to allow users to change the current language and have their language selection be remembered through the use of cookies.
To go through this recipe we need a fully internationalized application to work with. Go through the entire recipe Translating database records with the Translate behavior.
We also need an application layout that we can modify. Copy the file default.ctp
from cake/libs/view/layouts
to your app/views/layouts
directory.
app/config/bootstrap.php
file and add the following right above the PHP closing tag:Configure::write('Config.languages', array( 'eng' => __('English', true), 'spa' => __('Spanish', true) ));
default.ctp
layout file located in your app/views/layouts
folder and add the following where you want the list of languages to be included (such as right above the call to the flash()
method of the Session
component):<div style="float: right"> <?php $links = array(); $currentLanguage = Configure::read('Config.language'), foreach(Configure::read('Config.languages') as $code => $language) { if ($code == $currentLanguage) { $links[] = $language; } else { $links[] = $this->Html->link($language, array('lang' => $code)); } } echo implode(' - ', $links); ?> </div>
app_controller.php
and place it in your app/
folder, with the following contents:<?php class AppController extends Controller { public $components = array('Language', 'Session'), } ?>
language.php
and place it in your app/controller/components
folder, with the following contents:<?php class LanguageComponent extends Object { public $controller = null; public $components = array('Cookie'), public $languages = array(); public function initialize($controller) { $this->controller = $controller; if (empty($languages)) { $this->languages = Configure::read('Config.languages'), } $this->set(); } public function set($language = null) { $saveCookie = false; if (empty($language) && isset($this->controller)) { if (!empty($this->controller->params['named']['lang'])) { $language = $this->controller->params['named']['lang']; } elseif (!empty($this->controller->params['url']['lang'])) { $language = $this->controller->params['url']['lang']; } if (!empty($language)) { $saveCookie = true; } } if (empty($language)) { $language = $this->Cookie->read('language'), if (empty($language)) { $saveCookie = true; } } if (empty($language) && !array_key_exists($language, $this->languages)) { $language = Configure::read('Config.language'), } Configure::write('Config.language', $language); if ($saveCookie) { $this->Cookie->write('language', $language, false, '1 year'), } } } ?>
If you now browse to http://localhost/articles
you should see the list of articles, and in the top-right area, a link to switch the current language to Spanish. Clicking on it should display the Spanish version of the articles, and change all available texts to the selected language, as shown in the following screenshot:
We start by defining all available languages so that we can easily include a link to switch the current language. We use this list to construct the list of links and place it in the default.ctp
layout file, only allowing clicks on languages other than the current application language.
The current language is set in CakePHP's configure variable, Config.language
, which is set to a default language (eng
in our case) in the configuration file bootstrap.php
. When a language change is needed, this setting should be changed before the first use of a translator function.
To keep a clean controller, we decided to create a component called Language
to handle language changes. This component will look for a named or URL parameter called lang
. If no language is specified, the component will look for the current language by looking into a cookie.
If no cookie is set, or if a language change is requested, the component will save the current language in a cookie named language
that lasts for one year.
3.145.191.134