CakePHP 2 Application Cookbook
上QQ阅读APP看书,第一时间看更新

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:

  1. Open the routes.php file in app/Config/ and add the following lines to it:
    Router::connect('/:language/:controller/:action/*', array(), array(
      'language' => '[a-zA-Z]{3}',
      'persist' => array('language')
    ));
  2. Open your AppController.php file in app/Controller/ and add the following beforeFilter() method:
    public function beforeFilter() {
      parent::beforeFilter();
      if (!empty($this->request->params['language'])) {
        Configure::write('Config.language', $this->request->params['language']);
      }
    }
  3. Edit the ExampleController.php file in app/Controller/ and add the following language() method to it:
    public function language() {
      $this->set('language', Configure::read('Config.language'));
    }
  4. Edit the language.ctp file in app/View/Example/ and introduce the following content:
    <h2><?php echo __('Language Setting'); ?></h2>
    <p>
      <?php echo __('The current language is: %s', $language); ?>
    </p>
  5. 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 to do it...

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.