Translator.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /**
  2. * Translates strings with interpolation & pluralization support.
  3. * Extensible with custom dictionaries and pluralization functions.
  4. *
  5. * Borrows heavily from and inspired by Polyglot https://github.com/airbnb/polyglot.js,
  6. * basically a stripped-down version of it. Differences: pluralization functions are not hardcoded
  7. * and can be easily added among with dictionaries, nested objects are used for pluralization
  8. * as opposed to `||||` delimeter
  9. *
  10. * Usage example: `translator.translate('files_chosen', {smart_count: 3})`
  11. *
  12. * @param {object} opts
  13. */
  14. module.exports = class Translator {
  15. constructor (opts) {
  16. const defaultOptions = {
  17. locale: {
  18. strings: {},
  19. pluralize: function (n) {
  20. if (n === 1) {
  21. return 0
  22. }
  23. return 1
  24. }
  25. }
  26. }
  27. this.opts = Object.assign({}, defaultOptions, opts)
  28. this.locale = Object.assign({}, defaultOptions.locale, opts.locale)
  29. // console.log(this.opts.locale)
  30. // this.locale.pluralize = this.locale ? this.locale.pluralize : defaultPluralize
  31. // this.locale.strings = Object.assign({}, en_US.strings, this.opts.locale.strings)
  32. }
  33. /**
  34. * Takes a string with placeholder variables like `%{smart_count} file selected`
  35. * and replaces it with values from options `{smart_count: 5}`
  36. *
  37. * @license https://github.com/airbnb/polyglot.js/blob/master/LICENSE
  38. * taken from https://github.com/airbnb/polyglot.js/blob/master/lib/polyglot.js#L299
  39. *
  40. * @param {string} phrase that needs interpolation, with placeholders
  41. * @param {object} options with values that will be used to replace placeholders
  42. * @return {string} interpolated
  43. */
  44. interpolate (phrase, options) {
  45. const replace = String.prototype.replace
  46. const dollarRegex = /\$/g
  47. const dollarBillsYall = '$$$$'
  48. for (let arg in options) {
  49. if (arg !== '_' && options.hasOwnProperty(arg)) {
  50. // Ensure replacement value is escaped to prevent special $-prefixed
  51. // regex replace tokens. the "$$$$" is needed because each "$" needs to
  52. // be escaped with "$" itself, and we need two in the resulting output.
  53. var replacement = options[arg]
  54. if (typeof replacement === 'string') {
  55. replacement = replace.call(options[arg], dollarRegex, dollarBillsYall)
  56. }
  57. // We create a new `RegExp` each time instead of using a more-efficient
  58. // string replace so that the same argument can be replaced multiple times
  59. // in the same phrase.
  60. phrase = replace.call(phrase, new RegExp('%\\{' + arg + '\\}', 'g'), replacement)
  61. }
  62. }
  63. return phrase
  64. }
  65. /**
  66. * Public translate method
  67. *
  68. * @param {string} key
  69. * @param {object} options with values that will be used later to replace placeholders in string
  70. * @return {string} translated (and interpolated)
  71. */
  72. translate (key, options) {
  73. if (options && options.smart_count) {
  74. var plural = this.locale.pluralize(options.smart_count)
  75. return this.interpolate(this.opts.locale.strings[key][plural], options)
  76. }
  77. return this.interpolate(this.opts.locale.strings[key], options)
  78. }
  79. }