diff --git a/package.json b/package.json index d662b6d7b884f..e405b3f9214e0 100644 --- a/package.json +++ b/package.json @@ -144,6 +144,7 @@ "getos": "^3.1.0", "glob": "^7.1.2", "glob-all": "^3.1.0", + "globby": "^8.0.1", "good-squeeze": "2.1.0", "h2o2": "^8.1.2", "handlebars": "4.0.5", @@ -337,7 +338,6 @@ "fetch-mock": "^5.13.1", "geckodriver": "1.12.2", "getopts": "2.0.0", - "globby": "^8.0.1", "grunt": "1.0.1", "grunt-cli": "^1.2.0", "grunt-contrib-watch": "^1.1.0", diff --git a/packages/kbn-i18n/README.md b/packages/kbn-i18n/README.md index ba8858417221b..bcd9f26a054e8 100644 --- a/packages/kbn-i18n/README.md +++ b/packages/kbn-i18n/README.md @@ -33,21 +33,7 @@ For example: src/legacy/core_plugins/kibana/translations/fr.json ``` -When a new translation file is added, you have to register this file into -`uiExports.translations` array of plugin constructor parameters. For example: -```js -export default function (kibana) { - return new kibana.Plugin({ - uiExports: { - translations: [ - resolve(__dirname, './translations/fr.json'), - ], - ... - }, - ... - }); -} -``` +The engine scans `x-pack/plugins/*/translations`, `src/core_plugins/*/translations`, `plugins/*/translations` and `src/ui/translations` folders on initialization, so there is no need to register translation files. The engine uses a `config/kibana.yml` file for locale resolution process. If locale is defined via `i18n.locale` option in `config/kibana.yml` then it will be used as a base diff --git a/src/legacy/core_plugins/kibana/index.js b/src/legacy/core_plugins/kibana/index.js index c7a44ac2b04bd..d8f35fd56e2e1 100644 --- a/src/legacy/core_plugins/kibana/index.js +++ b/src/legacy/core_plugins/kibana/index.js @@ -134,8 +134,6 @@ export default function (kibana) { }; }, - translations: [], - mappings, uiSettingDefaults: getUiSettingDefaults(), }, diff --git a/src/legacy/core_plugins/timelion/index.js b/src/legacy/core_plugins/timelion/index.js index 3a1284eaacf90..5387d38789897 100644 --- a/src/legacy/core_plugins/timelion/index.js +++ b/src/legacy/core_plugins/timelion/index.js @@ -104,7 +104,6 @@ export default function (kibana) { category: ['timelion'], } }, - translations: [], }, init: require('./init.js'), }); diff --git a/src/server/i18n/index.js b/src/server/i18n/index.js index 6334f50bfaa4c..d010c5a8b5678 100644 --- a/src/server/i18n/index.js +++ b/src/server/i18n/index.js @@ -17,12 +17,45 @@ * under the License. */ +import { resolve } from 'path'; +import globby from 'globby'; import { i18n, i18nLoader } from '@kbn/i18n'; +import { fromRoot } from '../../utils'; + export async function i18nMixin(kbnServer, server, config) { - const { translationPaths = [] } = kbnServer.uiExports; const locale = config.get('i18n.locale'); + const translationsDirs = [fromRoot('src/ui/translations')]; + + const groupedEntries = await Promise.all([ + ...config.get('plugins.scanDirs').map(async path => { + const entries = await globby(`*/translations/${locale}.json`, { + cwd: path, + }); + return entries.map(entry => resolve(path, entry)); + }), + + ...config.get('plugins.paths').map(async path => { + const entries = await globby( + [`translations/${locale}.json`, `plugins/*/translations/${locale}.json`], + { + cwd: path, + } + ); + return entries.map(entry => resolve(path, entry)); + }), + + ...translationsDirs.map(async path => { + const entries = await globby(`${locale}.json`, { + cwd: path, + }); + return entries.map(entry => resolve(path, entry)); + }), + ]); + + const translationPaths = [].concat(...groupedEntries); + i18nLoader.registerTranslationFiles(translationPaths); const pureTranslations = await i18nLoader.getTranslationsByLocale(locale); diff --git a/src/server/kbn_server.js b/src/server/kbn_server.js index 977f3abf586c8..da63771112bd7 100644 --- a/src/server/kbn_server.js +++ b/src/server/kbn_server.js @@ -75,6 +75,9 @@ export default class KbnServer { // writes pid file pidMixin, + // scan translations dirs, register locale files, initialize i18n engine and define `server.getUiTranslations` + i18nMixin, + // find plugins and set this.plugins and this.pluginSpecs Plugins.scanMixin, @@ -83,7 +86,6 @@ export default class KbnServer { // setup this.uiExports and this.uiBundles uiMixin, - i18nMixin, indexPatternsMixin, // setup saved object routes diff --git a/src/ui/ui_exports/ui_export_types/index.js b/src/ui/ui_exports/ui_export_types/index.js index fa7847fccbf2a..c12c445540efd 100644 --- a/src/ui/ui_exports/ui_export_types/index.js +++ b/src/ui/ui_exports/ui_export_types/index.js @@ -61,10 +61,6 @@ export { shareContextMenuExtensions, } from './ui_app_extensions'; -export { - translations, -} from './ui_i18n'; - export { link, links, diff --git a/src/ui/ui_exports/ui_export_types/ui_i18n.js b/src/ui/ui_exports/ui_export_types/ui_i18n.js deleted file mode 100644 index 01c85b6883025..0000000000000 --- a/src/ui/ui_exports/ui_export_types/ui_i18n.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { flatConcatAtType } from './reduce'; -import { wrap, alias } from './modify_reduce'; - -// paths to translation files -export const translations = wrap(alias('translationPaths'), flatConcatAtType);