Improve i18n
I18n support improvement
This update contains :
- Support for using Accept-Language header when fetching required language
- Support for contextual and plural translations (see syntax below)
- Full set of utilities functions for translating with ease in each case and with full sprintf syntax support
- Full support for getting plural cases in 144 languages based on http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html?id=l10n/pluralforms
- Full backward compatibility for letting time to update each layout
- Fallback to main vtiger translation file in nothing found in module translation file
- Very few and minor modifications
Warning and discussion : Functions will only fetch values in languageStrings arrays. I don't really see the utility of separated js language strings and functions ?
Accept-Language Header
Vtiger will first try to find a user choosen locale in the user settings.
If none found, it will now try to use the Accept-Language header provided by the browser. It's especially useful in login screen for multilingual users.
Finally, it will still fallback to global configuration
Contextual and plural translations
Context translation
The use of context string lets tuning translation in special cases, e.g. taking care of gender.
Plural translations
Many languages have differents ways of taking plurals in account, from none to 6 plural forms.
Utilities functions for translations
The basic one is __(KEY_NAME)
that will return the value of KEY_NAME taken in vtiger.php translations file.
If you use m (__m(KEY_NAME, MODULE_NAME)
), it will return the value of KEY_NAME taken the module translations file (MODULE_NAME.php).
If you use x (__x(KEY_NAME, CONTEXT_STRING)
), it will return the value of KEY_NAME associated to the given CONTEXT_STRING.
If you use n (__n(KEY_NAME, COUNT)
), it will return the value of KEY_NAME linked to the right plural form for COUNT items.
You can mix all of these options : __mx
, __mn
, __xn
, __mxn
For instance, the actual vtranslate
function is the same than __m(KEY_NAME, $MODULE)
.
Taking care of context and plural in translations files
The pattern used for key naming is the same than JS library I18next (see https://www.i18next.com/plurals.html and https://www.i18next.com/context.html).
The context is simply added after key name separated by an underscore.
Plurals are written like in gettext way. For a language with 2 plural forms, you keep KEY_NAME for singular and KEY_NAME_PLURAL for plural. For a language with 3 or more plural forms, it will be KEY_NAME_0, KEY_NAME_1, ..., KEY_NAME_N for each cases
Mix of both is on the form KEY_NAME_CONTEXT_PLURAL for example.
Examples
Let's say that we have these values (totally useless in real life
in languages/en_us/users.php
$languageStrings = array(
'LBL_USER' => 'User',
'LBL_USER_PLURAL' => 'Users',
'LBL_USER_MALE' => 'Mister User',
'LBL_USER_FEMALE' => 'Miss User',
'LBL_CONNECTED_USERS' => '%d user is connected',
'LBL_CONNECTED_USERS_PLURAL' => '%d users are connected',
);
in vtiger.php
$languageStrings = array(
'LBL_USER_MALE_PLURAL' => 'Many main males users',
'LBL_USER_FEMALE_PLURAL' => 'Many main female users',
);
Calling __('LBL_USER')
will return 'LBL_USER' because no key is defined in vtiger.php
Calling __m('LBL_USER', $MODULE)
in a users Module layout will return 'User'
Calling __mn('LBL_USER', $MODULE, $CONNECTED_USERS_COUNT)
in a users module layout will return for instance '10 users are connected'
Calling __mxn('LBL_USER', $MODULE, 'FEMALE', $CONNECTED_USERS_COUNT)
in a users module layout will return 'Miss User' if $CONNECTED_USERS_COUNT = 1 and 'Many main female users' if $CONNECTED_USERS_COUNT > 1 (fallback to main translation file)