Quellcode durchsuchen

Allow locale inheritance: defaultLocale, this.uppy.locale, this.opts.locale

Mostly what @goto-bus-stop did in https://github.com/transloadit/uppy/commit/4f51deaaf7eb528902dc65ced6a7f16e37564c0e#diff-989af75a364b65c408abe1fc3e7ac0f4R34

> This patch allows locale keys passed to the main Uppy instance to override default keys in plugins. It's just one idea to kick things off, I'm not attached to this particular implementation.
>
> If we do this we need to make sure that all keys have unique names and that things specific to eg. a single service are "namespaced" (`transloaditEncoding` instead of `encoding`).
>
> The benefit to this is that there is a central point of configuration for languages, so there could be language packs with strings for eg Czech at `@uppy/lang-cz` (or `@uppy/langs/cz`) that would be very easy to use.
Artur Paikin vor 6 Jahren
Ursprung
Commit
4efc27675c

+ 2 - 4
packages/@uppy/core/src/index.js

@@ -73,11 +73,9 @@ class Uppy {
     this.opts = Object.assign({}, defaultOptions, opts)
     this.opts = Object.assign({}, defaultOptions, opts)
     this.opts.restrictions = Object.assign({}, defaultOptions.restrictions, this.opts.restrictions)
     this.opts.restrictions = Object.assign({}, defaultOptions.restrictions, this.opts.restrictions)
 
 
-    this.locale = Object.assign({}, defaultLocale, this.opts.locale)
-    this.locale.strings = Object.assign({}, defaultLocale.strings, this.opts.locale.strings)
-
     // i18n
     // i18n
-    this.translator = new Translator({locale: this.locale})
+    this.translator = new Translator([ defaultLocale, this.opts.locale ])
+    this.locale = this.translator.locale
     this.i18n = this.translator.translate.bind(this.translator)
     this.i18n = this.translator.translate.bind(this.translator)
 
 
     // Container for different types of plugins
     // Container for different types of plugins

+ 27 - 14
packages/@uppy/utils/src/Translator.js

@@ -9,24 +9,37 @@
  *
  *
  * Usage example: `translator.translate('files_chosen', {smart_count: 3})`
  * Usage example: `translator.translate('files_chosen', {smart_count: 3})`
  *
  *
- * @param {object} opts
+ * @param {object|Array<object>} locale Locale or list of locales.
  */
  */
 module.exports = class Translator {
 module.exports = class Translator {
-  constructor (opts) {
-    const defaultOptions = {
-      locale: {
-        strings: {},
-        pluralize: function (n) {
-          if (n === 1) {
-            return 0
-          }
-          return 1
+  constructor (locales) {
+    this.locale = {
+      strings: {},
+      pluralize: function (n) {
+        if (n === 1) {
+          return 0
         }
         }
+        return 1
       }
       }
     }
     }
 
 
-    this.opts = Object.assign({}, defaultOptions, opts)
-    this.locale = Object.assign({}, defaultOptions.locale, opts.locale)
+    if (Array.isArray(locales)) {
+      locales.forEach((locale) => this._apply(locale))
+    } else {
+      this._apply(locales)
+    }
+  }
+
+  _apply (locale) {
+    if (!locale || !locale.strings) {
+      return
+    }
+
+    const prevLocale = this.locale
+    this.locale = Object.assign({}, prevLocale, {
+      strings: Object.assign({}, prevLocale.strings, locale.strings)
+    })
+    this.locale.pluralize = locale.pluralize || prevLocale.pluralize
   }
   }
 
 
   /**
   /**
@@ -102,9 +115,9 @@ module.exports = class Translator {
   translateArray (key, options) {
   translateArray (key, options) {
     if (options && typeof options.smart_count !== 'undefined') {
     if (options && typeof options.smart_count !== 'undefined') {
       var plural = this.locale.pluralize(options.smart_count)
       var plural = this.locale.pluralize(options.smart_count)
-      return this.interpolate(this.opts.locale.strings[key][plural], options)
+      return this.interpolate(this.locale.strings[key][plural], options)
     }
     }
 
 
-    return this.interpolate(this.opts.locale.strings[key], options)
+    return this.interpolate(this.locale.strings[key], options)
   }
   }
 }
 }

+ 34 - 8
packages/@uppy/utils/src/Translator.test.js

@@ -6,17 +6,15 @@ const english = require('../../../../locales/en_US')
 describe('Translator', () => {
 describe('Translator', () => {
   describe('translate', () => {
   describe('translate', () => {
     it('should translate a string', () => {
     it('should translate a string', () => {
-      const translator = new Translator({ locale: russian })
+      const translator = new Translator(russian)
       expect(translator.translate('chooseFile')).toEqual('Выберите файл')
       expect(translator.translate('chooseFile')).toEqual('Выберите файл')
     })
     })
 
 
     it('should translate a string with non-string elements', () => {
     it('should translate a string with non-string elements', () => {
       const translator = new Translator({
       const translator = new Translator({
-        locale: {
-          strings: {
-            test: 'Hello %{who}!',
-            test2: 'Hello %{who}'
-          }
+        strings: {
+          test: 'Hello %{who}!',
+          test2: 'Hello %{who}'
         }
         }
       })
       })
 
 
@@ -27,9 +25,37 @@ describe('Translator', () => {
     })
     })
   })
   })
 
 
+  describe('translation strings inheritance / overriding', () => {
+    const launguagePackLoadedInCore = english
+    const defaultStrings = {
+      strings: {
+        youHaveChosen: 'You have chosen 123: %{fileName}'
+      }
+    }
+    const userSuppliedStrings = {
+      strings: {
+        youHaveChosen: 'Beep boop: %{fileName}'
+      }
+    }
+
+    it('should prioritize language pack strings from Core over default', () => {
+      const translator = new Translator([ defaultStrings, launguagePackLoadedInCore ])
+      expect(
+        translator.translate('youHaveChosen', { fileName: 'img.jpg' })
+      ).toEqual('You have chosen: img.jpg')
+    })
+
+    it('should prioritize user-supplied strings over language pack from Core', () => {
+      const translator = new Translator([ defaultStrings, launguagePackLoadedInCore, userSuppliedStrings ])
+      expect(
+        translator.translate('youHaveChosen', { fileName: 'img.jpg' })
+      ).toEqual('Beep boop: img.jpg')
+    })
+  })
+
   describe('interpolation', () => {
   describe('interpolation', () => {
     it('should interpolate a string', () => {
     it('should interpolate a string', () => {
-      const translator = new Translator({ locale: english })
+      const translator = new Translator(english)
       expect(
       expect(
         translator.translate('youHaveChosen', { fileName: 'img.jpg' })
         translator.translate('youHaveChosen', { fileName: 'img.jpg' })
       ).toEqual('You have chosen: img.jpg')
       ).toEqual('You have chosen: img.jpg')
@@ -38,7 +64,7 @@ describe('Translator', () => {
 
 
   describe('pluralization', () => {
   describe('pluralization', () => {
     it('should translate a string', () => {
     it('should translate a string', () => {
-      const translator = new Translator({ locale: russian })
+      const translator = new Translator(russian)
       expect(
       expect(
         translator.translate('filesChosen', { smart_count: 18 })
         translator.translate('filesChosen', { smart_count: 18 })
       ).toEqual('Выбрано 18 файлов')
       ).toEqual('Выбрано 18 файлов')