Source: services/translate.js

  1. import Ember from 'ember';
  2. /**
  3. * @module
  4. * @augments ember/Service
  5. */
  6. export default Ember.Service.extend({
  7. // -------------------------------------------------------------------------
  8. // Dependencies
  9. // -------------------------------------------------------------------------
  10. // Attributes
  11. // -------------------------------------------------------------------------
  12. // Actions
  13. // -------------------------------------------------------------------------
  14. // Events
  15. // -------------------------------------------------------------------------
  16. // Properties
  17. /**
  18. * Translations
  19. *
  20. * @type {?Object|ember/Object}
  21. */
  22. dictionary: null,
  23. // -------------------------------------------------------------------------
  24. // Observers
  25. // -------------------------------------------------------------------------
  26. // Methods
  27. /**
  28. * Set translation dictionary data
  29. *
  30. * @function
  31. * @param {Object|ember/Object} translations
  32. * @throws {ember.assert}
  33. * @returns {undefined}
  34. */
  35. setDictionary( translations ) {
  36. Ember.assert(
  37. 'services/translation.setDictionary() expects parameter to be an object',
  38. 'object' === Ember.typeOf( translations ) ||
  39. 'instance' === Ember.typeOf( translations )
  40. );
  41. this.set( 'dictionary', translations );
  42. },
  43. /**
  44. * Retrieve value for specified dictionary key
  45. *
  46. * @function
  47. * @param {String} key - Dictionary key to retrieve value for
  48. * @returns {String}
  49. */
  50. getKeyValue( key ) {
  51. let defaultKeyValue = 'KEY__NOT__PRESENT';
  52. let retrievedKey = this.get( 'dictionary' ).getWithDefault( key, defaultKeyValue );
  53. let returnValue;
  54. if ( defaultKeyValue !== retrievedKey ) {
  55. returnValue = retrievedKey;
  56. } else {
  57. Ember.warn( 'No translation match for key "' + key + '".' );
  58. returnValue = key;
  59. }
  60. return returnValue;
  61. },
  62. /**
  63. * @typedef {Object} translateKeyParameter
  64. * @property {String} key
  65. * @property {String} [pluralKey]
  66. * @property {String} [pluralCount]
  67. * @property {Object} [parameters]
  68. */
  69. /**
  70. * Translate provided key
  71. *
  72. * Supports
  73. * - singular/plural string substitution
  74. * - replacement of placeholder tokens in translation strings with passed parameters
  75. *
  76. * @function
  77. * @param {translateKeyParameter} data
  78. * @returns {String}
  79. */
  80. translateKey( data ) {
  81. Ember.assert(
  82. 'Argument must be an object',
  83. 'object' === Ember.typeOf( data ) &&
  84. 'array' !== Ember.typeOf( data )
  85. );
  86. data.parameters = data.parameters || {};
  87. let pluralErrorTracker = 0;
  88. // BEGIN: Pluralization error checking
  89. if ( !Ember.isEmpty( data.pluralKey ) ) {
  90. pluralErrorTracker++;
  91. }
  92. if ( !Ember.isEmpty( data.pluralCount ) ) {
  93. pluralErrorTracker++;
  94. }
  95. let token = data.key;
  96. let getTokenValue = ( value ) => {
  97. try {
  98. value = this.getKeyValue( value );
  99. } catch ( e ) {
  100. Ember.warn( 'Unable to translate key "' + value + '".' );
  101. }
  102. return value;
  103. };
  104. if ( 1 === pluralErrorTracker ) {
  105. Ember.warn( 'If either "pluralKey" or "pluralCount" are provided then both must be.' +
  106. 'Singular key value was returned.' );
  107. return getTokenValue( token );
  108. }
  109. // END: Pluralization error checking
  110. // Pluralization
  111. if ( !Ember.isEmpty( data.pluralCount ) && Number(data.pluralCount) > 1 ) {
  112. token = data.pluralKey;
  113. }
  114. let translatedString;
  115. translatedString = getTokenValue( token );
  116. // Parameter replacement
  117. Ember.keys( data.parameters ).map( key => {
  118. translatedString = translatedString.replace( '{' + key.replace( '$', '' ) + '}' , data.parameters[key] );
  119. });
  120. return translatedString;
  121. }
  122. });