diff --git a/src/editor/config/config.js b/src/editor/config/config.js index 8f8a20c52..0cc4845f9 100644 --- a/src/editor/config/config.js +++ b/src/editor/config/config.js @@ -151,6 +151,9 @@ export default { // Dom element el: '', + // Configurations for I18n + i18n: {}, + // Configurations for Undo Manager undoManager: {}, diff --git a/src/editor/index.js b/src/editor/index.js index 020b94488..19d2ff7a9 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -125,6 +125,12 @@ export default (config = {}) => { */ editor: em, + /** + * @property {I18n} + * @private + */ + I18n: em.get('I18n'), + /** * @property {DomComponents} * @private diff --git a/src/i18n/config.js b/src/i18n/config.js new file mode 100644 index 000000000..5f29b610a --- /dev/null +++ b/src/i18n/config.js @@ -0,0 +1,20 @@ +import en from './locale/en'; + +export default { + // Locale value + locale: 'en', + + // Fallback locale + localeFallback: 'en', + + // Detect locale by checkig browser language + detectLocale: 1, + + // Show warnings when some of the i18n resources are missing + debug: 0, + + // Messages to translate + messages: { + en + } +}; diff --git a/src/i18n/index.js b/src/i18n/index.js index 9e68a5d6e..1d61962d5 100644 --- a/src/i18n/index.js +++ b/src/i18n/index.js @@ -29,23 +29,30 @@ * @module I18n */ import { keys, isUndefined } from 'underscore'; -import en from './locale/en'; +import config from './config'; export default () => { - const { language } = window.navigator || {}; - const localeDef = language ? language.split('-')[0] : 'en'; - const config = { - locale: localeDef, - localeFallback: 'en', - counter: 'n', - messages: { en } - }; - return { name: 'I18n', config, + /** + * Initialize module + * @param {Object} config Configurations + * @private + */ + init(opts = {}) { + this.config = { ...config, ...opts }; + + if (this.config.detectLocale) { + this.config.locale = this._localLang(); + } + + this.em = opts.em; + return this; + }, + /** * Get module configurations * @returns {Object} Configuration object @@ -77,22 +84,11 @@ export default () => { return this.config.locale; }, - /** - * Initialize module - * @param {Object} config Configurations - * @private - */ - init(opts = {}) { - this.config = { ...config, ...opts }; - this.em = opts.em; - return this; - }, - /** * Get all messages * @param {String} [lang] Specify the language of messages to return * @param {Object} [opts] Options - * @param {Boolean} [opts.noWarn] Avoid warnings in case of missing language + * @param {Boolean} [opts.debug] Show warnings in case of missing language * @returns {Object} * @example * i18n.getMessages(); @@ -104,7 +100,7 @@ export default () => { const { messages } = this.config; lang && !messages[lang] && - this._warn(`'${lang}' i18n lang not found`, opts); + this._debug(`'${lang}' i18n lang not found`, opts); return lang ? messages[lang] : messages; }, @@ -166,7 +162,7 @@ export default () => { * @param {String} key Label to translate * @param {Object} [opts] Options for the translation * @param {Object} [opts.params] Params for the translation - * @param {Boolean} [opts.noWarn] Avoid warnings in case of missing resources + * @param {Boolean} [opts.debug] Show warnings in case of missing resources * @returns {String} * @example * obj.setMessages({ @@ -191,12 +187,18 @@ export default () => { if (!result) result = this._getMsg(key, localeFlb, opts); !result && - this._warn(`'${key}' i18n key not found in '${locale}' lang`, opts); + this._debug(`'${key}' i18n key not found in '${locale}' lang`, opts); result = result ? this._addParams(result, param) : result; return result; }, + _localLang() { + const nav = window.navigator || {}; + const lang = nav.language || nav.userLanguage; + return lang ? lang.split('-')[0] : 'en'; + }, + _addParams(str, params) { const reg = new RegExp(`\{([\\w\\d-]*)\}`, 'g'); return str.replace(reg, (m, val) => params[val] || '').trim(); @@ -221,9 +223,9 @@ export default () => { return result; }, - _warn(str, opts = {}) { - const { em } = this; - !opts.noWarn && em && em.logWarning(str); + _debug(str, opts = {}) { + const { em, config } = this; + (opts.debug || config.debug) && em && em.logWarning(str); } }; }; diff --git a/src/i18n/locale/en.js b/src/i18n/locale/en.js index a56f8d3f3..962b5424b 100644 --- a/src/i18n/locale/en.js +++ b/src/i18n/locale/en.js @@ -5,11 +5,15 @@ export default { modalTitle: 'Select Image', uploadTitle: 'Drop files here or click to upload' }, + // Here just as a reference, GrapesJS core doesn't contain any block, + // so this should be omitted from other local files blocks: { labels: { // 'block-id': 'Block Label', }, - categories: {} + categories: { + // 'category-id': 'Category Label', + } }, deviceManager: { device: 'Device', diff --git a/src/i18n/locale/index.js b/src/i18n/locale/index.js deleted file mode 100644 index 7f4284fa1..000000000 --- a/src/i18n/locale/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import en from './en'; - -export default { - en -}; diff --git a/test/specs/i18n/index.js b/test/specs/i18n/index.js index a309dac6e..b1ef98bde 100644 --- a/test/specs/i18n/index.js +++ b/test/specs/i18n/index.js @@ -32,6 +32,7 @@ describe('I18n', () => { em, locale, localeFallback, + detectLocale: 0, messages: { en: { msg } } @@ -82,12 +83,11 @@ describe('I18n', () => { en: { msg1 }, it: { msg1: `${msg1} it` } }); - expect(obj.t('msg2', { noWarn: 1 })).toBe(undefined); + expect(obj.t('msg2')).toBe(undefined); expect(obj.t('msg1')).toBe(msg1); }); test('Translate method with object structure', () => { - const opts = { noWarn: 1 }; const msg1 = 'Msg level 1'; const msg2 = 'Msg level 2'; obj.setLocale('en'); @@ -103,8 +103,8 @@ describe('I18n', () => { }); expect(obj.t('key1.msg1')).toBe(msg1); expect(obj.t('key1.key2.msg2')).toBe(msg2); - expect(obj.t('key1.key2.msg3', opts)).toBe(undefined); - expect(obj.t('key1.key3.msg2', opts)).toBe(undefined); + expect(obj.t('key1.key2.msg3')).toBe(undefined); + expect(obj.t('key1.key3.msg2')).toBe(undefined); }); test('Translate method with custom locale', () => {