Deprecated: Assigning the return value of new by reference is deprecated in /home/myriade/www/carnet/wp-settings.php on line 512

Deprecated: Assigning the return value of new by reference is deprecated in /home/myriade/www/carnet/wp-settings.php on line 527

Deprecated: Assigning the return value of new by reference is deprecated in /home/myriade/www/carnet/wp-settings.php on line 534

Deprecated: Assigning the return value of new by reference is deprecated in /home/myriade/www/carnet/wp-settings.php on line 570

Strict Standards: Declaration of Walker_Page::start_lvl() should be compatible with Walker::start_lvl(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::end_lvl() should be compatible with Walker::end_lvl(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::start_el() should be compatible with Walker::start_el(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::end_el() should be compatible with Walker::end_el(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_PageDropdown::start_el() should be compatible with Walker::start_el(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1244

Strict Standards: Declaration of Walker_Category::start_lvl() should be compatible with Walker::start_lvl(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::end_lvl() should be compatible with Walker::end_lvl(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::start_el() should be compatible with Walker::start_el(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::end_el() should be compatible with Walker::end_el(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_CategoryDropdown::start_el() should be compatible with Walker::start_el(&$output) in /home/myriade/www/carnet/wp-includes/classes.php on line 1442

Strict Standards: Redefining already defined constructor for class wpdb in /home/myriade/www/carnet/wp-includes/wp-db.php on line 306

Deprecated: Assigning the return value of new by reference is deprecated in /home/myriade/www/carnet/wp-includes/cache.php on line 103

Strict Standards: Redefining already defined constructor for class WP_Object_Cache in /home/myriade/www/carnet/wp-includes/cache.php on line 431

Deprecated: Assigning the return value of new by reference is deprecated in /home/myriade/www/carnet/wp-includes/query.php on line 61

Deprecated: Assigning the return value of new by reference is deprecated in /home/myriade/www/carnet/wp-includes/theme.php on line 1109

Strict Standards: Declaration of Walker_Comment::start_lvl() should be compatible with Walker::start_lvl(&$output) in /home/myriade/www/carnet/wp-includes/comment-template.php on line 1266

Strict Standards: Declaration of Walker_Comment::end_lvl() should be compatible with Walker::end_lvl(&$output) in /home/myriade/www/carnet/wp-includes/comment-template.php on line 1266

Strict Standards: Declaration of Walker_Comment::start_el() should be compatible with Walker::start_el(&$output) in /home/myriade/www/carnet/wp-includes/comment-template.php on line 1266

Strict Standards: Declaration of Walker_Comment::end_el() should be compatible with Walker::end_el(&$output) in /home/myriade/www/carnet/wp-includes/comment-template.php on line 1266

Strict Standards: Redefining already defined constructor for class WP_Dependencies in /home/myriade/www/carnet/wp-includes/class.wp-dependencies.php on line 31

Strict Standards: Redefining already defined constructor for class WP_Http in /home/myriade/www/carnet/wp-includes/http.php on line 61
Passage » 2009 » mars

Archive pour mars 2009

Ten software localization tips

Dimanche 22 mars 2009

You are about to write the best application ever with a fancy interface and sell it through your web site, and then you pause and ponder… How can I make it even more profitable right from the start? Drapeaux The answer is: localization!

Localization is adapting your software for a specific region or language by translating text elements and adding locale-specific formats. It is often abbreviated L10N (10 letters between “L” and “N”). Localization needs to be worked into the code right from the start. You can always translate an application later, but it will require more work.

10 ways to get a head start on localization:

1. Try to team up with a translator as soon as possible. He may have good tips for your particular application: game, text editor, back up software. If he is familiar with the language or the devkit you are using, he may even point to classes that will make things easier.

2. Identify all data that will require localization. Some of these are:

a) Buttons/labels/text fields/message boxes: Make them bigger (up to 50%) or leave room for resizing. English is compact; expect expansion with German and French. Also, the word “EXIT” on a round button may look spiffy, but the longer translated word may not. Design GUI accordingly.

Exit button example

b) Times/dates/numbers/currencies: Use only classes that are locale-sensitive. They will detect the regional settings of the user and write dates and numbers in the right order and with the right punctuation. Otherwise errors will creep in.

Original : January 5th, 2009
Right language. Wrong format : Janvier 5, 2009
Much better : 5 janvier 2009
An alternative (ISO 8601) : 2009-01-05 (YYYY-MM-DD)

c) Addresses/phone numbers: Do not hard code. Their formats are not only governed by languages, but also by countries.

Canada (French): 123, StreetName / France: StreetName, 123

d) Graphics/video clips: Make sure you have the uncompressed, layered files at hand so that added text can be translated with minimal manipulation. But it is easier to avoid graphic texts altogether.

e) Icons/colours/sounds: They can mean different things to different cultures, so be ready to make some changes there.

3. Punctuation/spacing: Punctuation and spacing rules differ according to language and region. For example, “34.8%” in English is localized to “34,8 %” in French. When this string is constructed at runtime, the translator cannot change the point to a comma. If a sentence needs a semi-colon, adding it at runtime may be a problem. In France, a space is required before the semi-colon or question mark; in Canada (French), there is no space before these two signs.

4. Compound messages/string concatenation: Avoid string concatenation such as this:

days_left = "3";
points_left = "15";
alert_message("You have " + days_left + " days to use the remaining " + points_left + " points from your account");

It will take a few more lines, but use something that includes stuff like:

GoodString = "new" String("You have %n days to use the remaining %m points from your account");
Etc;

However, it may just as well be better to avoid compound messages and use a less language dependant format such as “Days left: %n”, if possible.

Plurals can be formed by adding an “s” but also an “x” or replacing an “o” with an “i”, or using a completely different spelling such as in “mouse” and “mice”, so beware of hard coding an “s” as a plural form. Moreover, in some languages, the plural form for two objects can be different from the one used for three or more objects.

5. Use UTF-16. As a side note, when using XCode, make sure the IDE is set to UTF-16. I believe it defaults to UTF-8, but the string extractor uses UTF-16. It may not show in the emulator, but on a real device, some weird characters may show up.

6. Unicode collation: Make sure your string comparison methods use the right algorithm for sorting Unicode values. The sorting weight of characters is not determined by their position in the Unicode code charts. Moreover, the same accented character will sort differently from one language to the next.

7. Thinking of machine translation? Think again: How will the machine know, for example, which meaning of “Clear” to use? Clair, évident, limpide, transparent, degagé, tranquille… there are just too many! Actually, without context, even the translator may not know which one to choose. Put the description tag to good use. You’ll see why in this rather extreme example.

<Description> No comment provided by engineer. </Description>
<Position>%1 of %2 on %3, for %4.</Position>
<TranslationSet>
<base loc=”en”>%1 of %2 on %3, for %4.</base>
<tran loc=”fr_CA” origin=”"> ARRRRRGH :-( </tran>
</TranslationSet>

To avoid mistranslations, have the help files ready for the translator, screenshots, technical notes or any other documents that will provide context.

8. Terminology: Make up your mind and stick to it. These error messages all mean the same thing, but will raise your localization cost needlessly.

Not enough disk space / There is not enough disk space left  / Insufficient disk space / No space left on the disk

9. New versions/updates: Once your application is up and running in many languages, keep track of changes you make to your next version, so that only those changes will be translated.

10. Web site: And of course, present your customers with a well translated web site. Some tips on that in a future entry of “Passage: A bridge between two worlds”.

Happy coding! tradlogomini

Julie
PS: See also more localization tips!