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 ?
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
The use of context string lets tuning translation in special cases, e.g. taking care of gender.
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 :
For instance, the actual
vtranslate function is the same than
Taking care of context and plural in translations files
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.
Let's say that we have these values (totally useless in real life
$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', );
$languageStrings = array( 'LBL_USER_MALE_PLURAL' => 'Many main males users', 'LBL_USER_FEMALE_PLURAL' => 'Many main female users', );
__('LBL_USER') will return 'LBL_USER' because no key is defined in vtiger.php
__m('LBL_USER', $MODULE) in a users Module layout will return 'User'
__mn('LBL_USER', $MODULE, $CONNECTED_USERS_COUNT) in a users module layout will return for instance '10 users are connected'
__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)