Skip to content

Localization

nirix edited this page Feb 25, 2012 · 3 revisions

Localising Traq is easy, all language strings are passed through the l() function which passes the data to the loaded localisation class.

Things to know

Locale strings can contain HTML, if you would like to actually display \n then you will need to include and extra blackslash, like so: \\n.

If you would like to display HTML tags, the best way is by using htmlentities, like so: "emphasize text with the " . htmlentities("<em>") . " tag";.

The locale file

The locale files are placed in system/locale and are a PHP class that stores all the information.

The best way to start translating Traq is to take a look at the enus.php file.

How it works

Let's say we want to localize an error about how much time a user needs to wait before posting something again.

echo l('errors.you_must_wait_x_seconds_before_posting', 35);

This passes the string with a variable to the loaded locale class, in this case the English Locale_enUS class that extends the Locale class.

Once passed to the locale class, it will lookup the translation for the string we passed it, which is:

'errors' => array(
    'you_must_wait_x_seconds_before_posting' => "You must wait $1 seconds before posting"
)

The translation array is multidimensional, which can be accessed like we just did with the error message: errors.my_error, or errors.404.message and so on.

You may have noticed the $1 in the translation, this tells the Locale class to replace that with the first variable we passed to the l() function after the string, you can pass as many variables as you like and access with them with either $x, ${x} or the classic {x} (x being 1, 2, 3, etc).

Plurals

Now what if there is one second remaining? the message will read as .. 1 seconds .., this doesn't look right, that is why in Traq 3.0 the new localisation system allows for plurals as requested.

To utilize the plural replacement feature, format strings like so

"You must wait {plural:$1,{$1 second|$1 seconds}} seconds before posting"

This will pass the value to a method in the Locale class that will calculate what type of form to use.

How this works is, Locale::calculate_numeral will return 0 if the value is 1 but if the value is anything but that, it will return 1.

Multiple forms

To change the calculate_numeral method for other languages, in your locale class define your own static function named calculate_numeral that takes one parameter (which is the value from the locale string), then insert your code that will determine which form to use based on that parameter.

So lets say we want to display how many bottles of scotch are on the shelf, but instead of displaying 0 bottles we want to display no bottles, this is what we'd do

public static function calculate_numeral($numeral)
{
    return ($numeral > 1 or $numeral < -1) ? ($numeral == 0 ? 2 : 1) : 0;
}

And for our locale string

'there_are_x_bottles' => 'There {plural:$1, {is $1 bottle|are $1 bottles|are no bottles}} of scotch on the shelf'

Then to use the string

l('there_are_x_bottles', 0); // There are no bottles of scotch on the shelf
l('there_are_x_bottles', 1); // There is 1 bottle ...
l('there_are_x_bottles', 2); // There are 2 bottles ...
Clone this wiki locally