CakePHP 1.2 i18n/l10n

A few month ago I started working with the CakePHP framework. I needed the i18n functionality that was in version 1.2 (late alpha). After a lot of research I was able to get what I needed. I wrote up my findings and submitted this to the CakePHP developers. They have accepted my submission on using i18n in 1.2 and it will appear in the CakePHP 1.2 Manual. This is my first contribution back to the open source community and while it is just a small bit, I am quite proud to have made even a small contribution back to what has given me so much. Since the 1.2 manual is not yet available I thought I’d post my contribution here:

Localization and Internationalization

What is the difference? Localization refers to the ADAPTATION of a product, application or document content to meet the language, cultural and other requirements of a specific target market (a “locale”). Internationalization is the DESIGN AND DEVELOPMENT of a product, application or document content that ENABLES easy localization for target audiences that vary in culture, region, or language.

How to Use Localization

  1. Include l10n Class
    uses('L10n');
    
    class OrderController extends AppController {
        ...
    }
  2. Create Language File Specific language translations are placed here:
    locale/eng/LC_MESSAGES/default.po (English)
    locale/fre/LC_MESSAGES/default.po (French)

    Language directories must be named with the official three-digit language code; you can find these here: http://www.loc.gov/standards/iso639-2/php/code_list.php

  3. Populate Language file Create entries in the appropriate default.po file in this form:
    msgid  "close_window"
    msgstr "Close"
    
    msgid  "where_pin"
    msgstr "Where is my PIN?"

    There is a limit of 1014 characters in a single msgstr.

  4. Using Use the underscore-underscore method, providing the msgid as the first parameter.
    __("closeWindow");
    __("closeWindow", true);

    If the msgid provided is not found, then the provided value id used, hence some people like to use the default text as the msgid:

    __("Close Window");

    With the second parameter as true the value is returns, without the second parameter is echo’d. If you see your msgid on your page instead of cooresponding msgstr, and the msgid/msgstr pair exists in the relevant default.po file, then you probably are missing dbouel quotes around the msgid or msgstr entry.

  5. Selecting Language To select the language you want:
    $this->L10n = new L10n();$this->L10n->get("en");
    $_SESSION['Config']['language'] = "en";

    Use the first two-digits of the language code (yes, I know it is weird to use two-digits here and three-digits as the language directory name). Configure::write(‘Config.language’, “en”) will work in place of $_SESSION['Config']['language'] = “en” in the future, but it does not work as of 1.2.0.4798alpha.

Real-Life Implementation Example

I created a language helper method:

public function setLang($language = 'en') {
    $this->L10n = new L10n();
    $this->L10n->get($language);
    //Configure::write('Config.language', $language);
    $_SESSION['Config']['language'] = $language;
}

Then I use it in my controller methods as needed.

function balance() {
    Utility::setLang(LOCALE);
    ...
}

And LOCALE is a constant = “en”.

Special Characters

Save the default.po files with an encoding of ISO-8859-1 htmlentities will not render correctly if when used in $form->error() unless you turn off the espcae option:

echo $form->error('Card.cardNumber', __("errorCardNumber", true), array('escape' => false));