Skip to content

Improve i18n

Bartouille requested to merge bertrand.wattel/vtigercrm:improve_i18n into master

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)

Merge request reports