User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
en:devel:cbtranslation [2017/07/06 19:42]
joebordes
en:devel:cbtranslation [2018/12/27 12:23] (current)
joebordes [cbtranslation::get()]
Line 5: Line 5:
   *add strings to other modules with no code changes   *add strings to other modules with no code changes
   *more control of labels: avoid duplicates   *more control of labels: avoid duplicates
-  *I/E +  *Import/Export 
-  *all module advantages: mass edit+  *all module advantages: mass edit, deduplication
   *modify any label easily   *modify any label easily
   *easier to translate: external tools   *easier to translate: external tools
   *correct functionality of picklist search   *correct functionality of picklist search
   *possibility to translate values on modules, not just labels   *possibility to translate values on modules, not just labels
 +  *Support for using Accept-Language header when fetching required language: [[https://​github.com/​tsolucio/​corebos/​blob/​master/​modules/​cbtranslation/​cbtranslation.php#​L178|getLanguage]]
 +  *Support for contextual and plural translations with full sprintf syntax (see syntax below)
 +  *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
  
 =====Cons===== =====Cons=====
Line 18: Line 22:
   *modifying and adding strings is harder: cbupdater?   *modifying and adding strings is harder: cbupdater?
  
-=====Guide===== 
  
-This update contains :+=====Accept-Language Header=====
  
-  *Support for using Accept-Language header when fetching required language +[[https://github.com/tsolucio/corebos/blob/master/modules/cbtranslation/cbtranslation.php#​L178|cbTranslation::​getLanguage()]]
-  *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+
  
 +Will first try to find a user chosen locale in the user settings.
  
-====Accept-Language ​Header====+If none found, it will next try to use the Accept-Language ​header provided by the browser. This is especially useful in the login screen for multilingual users.
  
-Will first try to find a user choosen locale in the user settings.+Finally, it will fallback ​to the global configuration
  
-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.+=====Contextual and plural translations=====
  
-Finally, it will fallback to global configuration+====Context translation====
  
-====Contextual and plural translations==== 
- 
-===Context translation=== 
 The use of context string lets tuning translation in special cases, e.g. taking care of gender. The use of context string lets tuning translation in special cases, e.g. taking care of gender.
  
-===Plural translations=== +====Plural translations====
-Many languages have differents ways of taking plurals in account, from none to 6 plural forms.+
  
-===Utilities functions for translations=== +Many languages have different ways of taking plurals into account, from none to 6 plural forms.
-The basic one is <wrap hi>​__(KEY_NAME)</​wrap>​ that will return the value of KEY_NAME taken in main translations file.+
  
-If you use m (<wrap hi>​__m(KEY_NAME,​ MODULE_NAME)</​wrap>​),​ it will return the value of KEY_NAME taken the module translations file (MODULE_NAME.php).+====cbtranslation::​get()====
  
-If you use x (<wrap hi>​__x(KEY_NAME,​ CONTEXT_STRING)<​/wrap>), it will return the value of KEY_NAME associated to the given CONTEXT_STRING.+The [[https://​github.com/​tsolucio/​corebos/​blob/​master/​modules/​cbtranslation/​cbtranslation.php#​L225|cbtranslation::​get()]] method has full support for context and pluralsamong other features.
  
-If you use n (<wrap hi>__n(KEY_NAME, COUNT)</​wrap>​), it will return the value of KEY_NAME linked ​to the right plural form for COUNT items.+The basic usage is <wrap hi>cbtranslation::​get('​friend'​)</​wrap> ​that will return the value of '​friend'​ taken from the module cbtranslation values (equivalent ​to the previous main translation file in include/​language).
  
-You can mix all of these options : <wrap hi>__mx__mn, __xn, __mxn</​wrap>​+Next we can pass in the module as we did before with getTranslatedString, ​<wrap hi>cbtranslation::​get('​friend'​,'​Users'​)</​wrap>​, which will return the value of '​friend'​ taken from the Users module translations entries in the database.
  
-For instance, the actual getTranslatedString function ​is the same than __m(KEY_NAME,​ $MODULE).+The third parameter ​is an array with a set of options for the translation.
  
-===Taking care of context ​and plural in translations files=== +  * language ​=> <​String>​ language to translate against, if not set $current_language will be used 
-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).+  * context => <​String>​ label modifier ​for specific translation contexts, like gender. The context ​is simply added after key name separated by an underscore. 
 +  * count => <​Integer>​ label modifier for plurals. ​Plurals are written following gettext format. For a language with 2 plural forms, you keep KEY_NAME for singular ​and KEY_NAME_PLURAL for pluralFor a language with 3 or more plural forms, it will be KEY_NAME_0, KEY_NAME_1, ​..., KEY_NAME_N for each case
  
-The context is simply added after key name separated by an underscore.+Some examples would be:
  
-Plurals are written like in gettext way. For a language ​with 2 plural formsyou keep KEY_NAME for singular and KEY_NAME_PLURAL ​for plural. For a language ​with 3 or more plural formsit will be KEY_NAME_0KEY_NAME_1...KEY_NAME_N ​for each cases+  * <wrap hi>​cbtranslation::​get('​friend','​Users',​array('​language'​=>'​en_us'​))</​wrap>​ which will search ​in english 
 +  * <wrap hi>​cbtranslation::​get('​friend','​Users',​array('​language'​=>'​es_es'​))</​wrap>​ which will search in spanish 
 +  * <wrap hi>​cbtranslation::​get('​friend'​,'​Users',​array('​language'​=>'​en_us','​count'​=>​2))</​wrap>​ which will search in english ​for the plural ​form of the label: '​friend_PLURAL'​ 
 +  * <wrap hi>​cbtranslation::​get('​friend','​Users',​array('​language'​=>'​en_us'​,'​count'​=>​1))</​wrap>​ which will search in english for the singular form of the label: '​friend'​ 
 +  * <wrap hi>​cbtranslation::​get('​friend'​,'​Users'​,array('​language'​=>'​en_us'​,'​count'​=>​2,​ '​context'​=>'​female'​))</​wrap>​ which will search in english ​for the plural form of the label with '​female'​ suffix: '​friend_female_PLURAL'​
  
-Mix of both is on the form KEY_NAME_CONTEXT_PLURAL ​for example.+Finally, you can add more parameters to support sprintf formatting like this: <wrap hi>​cbtranslation::​get('​friendcountry','​Users',​array('​language'​=>'​en_us','​context'​=>'​female','​count'​=>​2),​2,'​England'​)</​wrap>​ 
 + 
 +You can [[https://​github.com/​tsolucio/​coreBOSTests/​blob/​master/​modules/​cbtranslation/​cbtranslationTest.php|find a set of examples in our unit test for this module]].
  
  
 ===Examples=== ===Examples===
-Let's say that we have these values ​(totally useless in real life) :+Let's say that we have these values
  
-in language/​en_us.lang.php 
 <​code>​ <​code>​
-$app_strings = array( 
 '​LBL_USER'​ => '​User',​ '​LBL_USER'​ => '​User',​
 '​LBL_USER_PLURAL'​ => '​Users',​ '​LBL_USER_PLURAL'​ => '​Users',​
-'​LBL_USER_MALE'​ => 'Mister ​User',​ +'​LBL_USER_MALE'​ => 'Male User',​ 
-'​LBL_USER_FEMALE'​ => 'Miss User',+'​LBL_USER_FEMALE'​ => 'Female ​User', 
 +'​LBL_USER_FEMALE_PLURAL'​ => 'Many female users',
 '​LBL_CONNECTED_USERS'​ => '%d user is connected',​ '​LBL_CONNECTED_USERS'​ => '%d user is connected',​
 '​LBL_CONNECTED_USERS_PLURAL'​ => '%d users are connected',​ '​LBL_CONNECTED_USERS_PLURAL'​ => '%d users are connected',​
-); 
-</​code>​ 
-<​code>​ 
-$mod_strings = array( 
-'​LBL_USER_MALE_PLURAL'​ => 'Many main males users',​ 
-'​LBL_USER_FEMALE_PLURAL'​ => 'Many main female users',​ 
-); 
 </​code>​ </​code>​
  
-Calling <wrap hi>__('​LBL_USER'​)</​wrap>​ will return 'LBL_USER' ​because no key is defined in vtiger.php+Calling <wrap hi>cbtranslation::​get('​LBL_USER'​, $MODULE)</​wrap>​ will return 'User'
  
-Calling <wrap hi>__m('​LBL_USER',​ $MODULE)</​wrap> ​in a users Module layout ​will return '​User'​+Calling <wrap hi>cbtranslation::​get('​LBL_USER',​ $MODULE, array('​count'​=>​$CONNECTED_USERS_COUNT))</​wrap>​ will return ​'​Users'​ if $CONNECTED_USERS_COUNT > 1 and '​User' ​if $CONNECTED_USERS_COUNT = 1
  
-Calling <wrap hi>__mn('LBL_USER', $MODULE, $CONNECTED_USERS_COUNT)</​wrap> ​in a users module layout ​will return for instance '10 users are connected'​+Calling <wrap hi>cbtranslation::​get('LBL_CONNECTED_USERS', $MODULE, array('​count'​=>​$CONNECTED_USERS_COUNT),​$CONNECTED_USERS_COUNT)</​wrap>​ will return for instance '10 users are connected'​
  
-Calling <wrap hi>__mxn('​LBL_USER',​ $MODULE, '​FEMALE',​ $CONNECTED_USERS_COUNT)</​wrap> ​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)+Calling <wrap hi>cbtranslation::​get('​LBL_USER',​ $MODULE, ​array('​context'​=>​'​FEMALE',​'​count'​=>​$CONNECTED_USERS_COUNT))</​wrap>​ will return 'Female ​User' if $CONNECTED_USERS_COUNT = 1 and 'Many female users' if $CONNECTED_USERS_COUNT > 1
  
 +===== cbtranslation webservice=====
  
 +There is currently no webservice interface to this module'​s translation services. We could enhance the webservice getTranslatedString method, which, I think, would be the correct way to proceed.
  
 +In the mean time, a normal query should get you the translation you need:
  
 +<code SQL>
 +select i18n from cbtranslation where translation_key = '​friend'​ and locale='​es_es'​
 +select i18n,​Products.productname from cbtranslation where Products.productname = 'Sexy Leggings';​
 +</​code>​
 =====References===== =====References=====
 +
 +This enhancement to coreBOS is based on the [[http://​code.vtiger.com/​vtiger/​vtigercrm/​merge_requests/​238|work of @bertrand.wattel]]. **Thank you very much!!** ​ I'm sure vtiger will pay just as much attention to your effort as I did LOL
  
   *http://​code.vtiger.com/​vtiger/​vtigercrm/​merge_requests/​238   *http://​code.vtiger.com/​vtiger/​vtigercrm/​merge_requests/​238