Internationalization == globalization
Ability of an app to be adapted to various languages and regions without engineering changes.
i.e. regardless of locale chosen. Developer's tasks.
Localization
The process of adapting software for a specific region or language by adding locale-specific components and translating text.
Translator tasks.
A data set that includes info about language, country, formats, currencies etc. Usually varies per country. Sometimes there are sub-variations.
Unicode Common Locale Data Repository
cldr.unicode.org Huge data set of i18n data per locale. Used by companies such as Apple, Google, IBM, Microsoft, Adobe, lots of Linux distribs. Java, Perl, Python, jQuery, PHP intl and more.Libraries for C and Java that use CLDR data for message formatting, locale selection etc.
echo \MessageFormatter::formatMessage(
'en_US', 'Value: {value, number}', ['value' => 123456,789]
);
// Value: 123,456.789
echo \MessageFormatter::formatMessage(
'en_US', 'Price: {price, number, currency}', ['price' => 100]
);
// Price: $100.00
echo \MessageFormatter::formatMessage(
'en_US', 'Value: {value, number, percent}', ['value' => 123]
);
// Value: 123%
echo \MessageFormatter::formatMessage(
'en_US', 'Date: {d, date, short} | {d, date, medium} | {d, date, long}
| {d, date, full}', ['d' => $d]
);
// Date: 4/18/15 | Apr 18, 2015 | April 18, 2015
| Saturday, April 18, 2015
echo \MessageFormatter::formatMessage(
'ru_UA', 'Date: {d, date, short} | {d, date, medium} | {d, date, long}
| {d, date, full}', ['d' => $d]
);
// Дата: 18.04.15 | 18 апр. 2015 г. | 18 апреля 2015 г.
| суббота, 18 апреля 2015 г.
echo \MessageFormatter::formatMessage(
'en_US', '{n,number} is spelled as {n, spellout}', ['n' => 42]
);
// 42 is spelled as forty-two
echo \MessageFormatter::formatMessage(
'en_US', 'I am {n, spellout,%spellout-ordinal} agent', ['n' => 47]
);
// I am forty-seventh agent
$message = 'Здесь {n, plural, =0{котов нет} =1{есть один кот} one{# кот}
few{# кота} many{# котов} other{# кота}}!';
echo \MessageFormatter::formatMessage('ru_UA', $message, ['n' => 1]);
// Здесь есть один кот!
$message = 'There {n, plural, =0{are no cats}
=1{is one cat} other{are # cats}}!';
echo \MessageFormatter::formatMessage('en_US', $message, ['n' => 1]);
// There is one cat!
echo \Yii::t('app', 'You are the {n, ordinal} visitor here!', ['n' => 42]);
// You are the 42nd visitor here!
echo \Yii::t('app', '{name} is a {gender} and {gender, select, female{she}
male{he} other{it}} loves Yii!', [
'name' => 'Snoopy',
'gender' => 'dog',
]);
// Snoopy is a dog and it loves Yii!
Intl is powerful!
Positional ones could be used:
$message = 'There {0, plural, =0{are no cats}
=1{is one cat} other{are # cats}} except {1}!';
echo \MessageFormatter::formatMessage('en_US', $message, [1, 'Simon']);
intl relies on CLDR data which is kinda more than is exposed via extension API. Can we access raw data?
new \ResourceBundle($resourceFileName, $resourceDirName);
$resourceDirName = null
means root dir of intl internal resources.
icudt49.dll
if you're on Windows or try building resources from source.
private function dumpResourceBundle($bundle, $depth = 0)
{
if ($bundle === null) {
return 'NULL';
} elseif (is_scalar($bundle)) {
return $bundle;
}
$out = '';
foreach ($bundle as $k => $v) {
$out .= str_repeat(' ', $depth) . $k . ' = ';
if ($v instanceof \ResourceBundle || is_array($v)) {
$out .= " [\n";
$out .= $this->dumpResourceBundle($v, $depth + 1);
$out .= str_repeat(' ', $depth) . "\n]\n";
}
else {
$out .= $v . "\n";
}
}
return $out;
}
new \ResourceBundle('en_UK', null);
Instead of en_UK
try more locales. If there's no data, try en
.
new \ResourceBundle('en_US', ...);
Less useful:
new \ResourceBundle(..., null);
Give it a locale and it will show you plurals format, selectordinal format etc.
As little work as possible
English or keys.in.english
.
Doens't really matter.
PHP arrays are OK for non-tech people.
A tool that scans code and updates translation files automatically adding new strings and removing old ones.
We have it in Yii ;)
Use ISO-639-2: es, en, fr or RFC-5645: zh_CN, ru_UA.
Locale::canonicalize($language);