
Handling languages
When building a multi-language application, you may want to allow your users to change the language of the content they're viewing through the URL.
In this recipe, we'll look at how you can use routing to deliver content in different languages.
Getting ready
First, we'll need a controller to work with, so create an ExampleController.php
file in app/Controller/
with the following content:
<?php App::uses('AppController', 'Controller'); class ExampleController extends AppController { }
We'll then need a view, so create a file named language.ctp
in app/View/Example/
.
How to do it...
Perform the following steps:
- Open the
routes.php
file inapp/Config/
and add the following lines to it:Router::connect('/:language/:controller/:action/*', array(), array( 'language' => '[a-zA-Z]{3}', 'persist' => array('language') ));
- Open your
AppController.php
file inapp/Controller/
and add the followingbeforeFilter()
method:public function beforeFilter() { parent::beforeFilter(); if (!empty($this->request->params['language'])) { Configure::write('Config.language', $this->request->params['language']); } }
- Edit the
ExampleController.php
file inapp/Controller/
and add the followinglanguage()
method to it:public function language() { $this->set('language', Configure::read('Config.language')); }
- Edit the
language.ctp
file inapp/View/Example/
and introduce the following content:<h2><?php echo __('Language Setting'); ?></h2> <p> <?php echo __('The current language is: %s', $language); ?> </p>
- Finally, navigate to
/eng/example/language
and then navigate to/esp/example/language
to see the website change language. This can be seen in the following screenshot:
How it works...
Here, we first defined a route to handle our language setting via the URL. For this we used the Router::connect()
method to register a new route. The first argument is the route template. You'll notice that we defined parts of the URL starting with a :
. This character delimits a named element, which we'll want to capture. The second argument was left as an empty array, as we're not specifying any default route parameters. Finally, the third argument had two keys. The first, language
, defines the regular expression for our language
route element. Here, we're simply stating that it must be a three character string, which matches with the locale codes in the framework. The second key, persist
, tells CakePHP that we want all URLs to have this element included. This helps keep our application consistent for all links.
We then added a beforeFilter()
method to our AppController
class, which reads the CakeRequest::$params
array to get the value of language
passed via the URL. This is then set to the Config.language
configuration option, which sets the default language for the application.
To test the functionality that we added, we created a language()
method on our ExampleController
. This method reads the value of the Config.language
configuration option and sets it to a view variable named $language
. Then, in our view, we output some translated strings, as well as the $language
variable. When changing the value of the language in your URL, you'll see how it updates the default setting in the framework. Then, if you create some translations of your strings for the given URLs, you would see the view change language.
To further extend the functionality of the language setting, you could add a list of default languages that your applications support. Bear in mind that when a translation is not found, the strings using __()
or any other various translation functions will simply default to the given string.
See also
- The Using the I18n shell recipe from Chapter 9, Creating Shells.
- The Translations recipe from Chapter 10, View Templates.