Translate the Kibana welcome message

Translates the start-up message (“Kibana is loading ...”)in the Jade template.

To be done:
 - Means to register the core plugin translations. They are currently added
in the fixtures directory as static files. Need to be generated on the fly.
This commit is contained in:
Martin Hickey 2016-07-25 14:58:54 +01:00
parent f1974ca2ab
commit 10db4585bd
7 changed files with 136 additions and 8 deletions

View file

@ -0,0 +1,4 @@
{
"CORE-WELCOME_MESSAGE": "is loading. Give me a moment here. I'm loading a whole bunch of code. Don't worry, all this good stuff will be cached up for next time!",
"CORE-WELCOME_ERROR": "Kibana did not load properly. Check the server output for more information."
}

View file

@ -0,0 +1,4 @@
{
"CORE-WELCOME_MESSAGE": "is loading. Give me a moment here. I'm loading a whole bunch of code. Don't worry, all this good stuff will be cached up for next time!",
"CORE-WELCOME_ERROR": "Kibana did not load properly. Check the server output for more information."
}

View file

@ -81,6 +81,7 @@
"@spalger/test-subj-selector": "0.2.1",
"@spalger/ui-ace": "0.2.3",
"JSONStream": "1.1.1",
"accept-language-parser": "1.1.2",
"angular": "1.4.7",
"angular-bootstrap-colorpicker": "3.0.19",
"angular-elastic": "2.5.0",
@ -185,6 +186,7 @@
"event-stream": "3.3.2",
"expect.js": "0.3.1",
"faker": "1.1.0",
"fs-extra": "0.30.0",
"grunt": "1.0.1",
"grunt-aws-s3": "0.14.5",
"grunt-babel": "5.0.1",

View file

@ -1,4 +1,5 @@
import expect from 'expect.js';
import fse from 'fs-extra';
import i18n from '../i18n/i18n';
import path from 'path';
import process from 'child_process';
@ -6,11 +7,18 @@ import Promise from 'bluebird';
const PATH_SEPARATOR = path.sep;
const DATA_PATH = __dirname + PATH_SEPARATOR + 'fixtures';
const TRANSLATION_BACKUP_PATH = DATA_PATH + '/translations_backup';
const translationStorePath = i18n.getTranslationStoragePath();
describe('Test registering translations for test_plugin_1', function () {
const pluginName = 'test_plugin_1';
const pluginTranslationPath = DATA_PATH + PATH_SEPARATOR + 'translations' + PATH_SEPARATOR + pluginName;
before(function (done) {
backupTranslations(done);
});
it('Register translations' , function (done) {
let result = true;
const translationFiles = [
@ -54,13 +62,16 @@ describe('Test registering translations for test_plugin_1', function () {
});
after(function (done) {
const translationStorePath = i18n.getTranslationStoragePath();
process.execSync('rm -rf ' + translationStorePath);
done();
restoreTranslations(done);
});
});
describe('Test registering translations for test_plugin_1 and test_plugin_2', function () {
before(function (done) {
backupTranslations(done);
});
it('Register translations for test_plugin_1' , function (done) {
let result = true;
const pluginName = 'test_plugin_1';
@ -120,9 +131,7 @@ describe('Test registering translations for test_plugin_1 and test_plugin_2', fu
});
after(function (done) {
const translationStorePath = i18n.getTranslationStoragePath();
process.execSync('rm -rf ' + translationStorePath);
done();
restoreTranslations(done);
});
});
@ -193,3 +202,44 @@ function checkRegisteredLanguages(expectedLanguages, done) {
done();
});
}
function backupTranslations(done) {
const translationStorePath = i18n.getTranslationStoragePath();
fse.copy(translationStorePath, TRANSLATION_BACKUP_PATH, function (err) {
if (err) {
console.error(err);
done();
return;
}
fse.emptyDir(translationStorePath, function (err) {
if (err) {
console.error(err);
}
done();
});
});
}
function restoreTranslations(done) {
const translationStorePath = i18n.getTranslationStoragePath();
fse.emptyDir(translationStorePath, function (err) {
if (err) {
console.error(err);
done();
return;
}
fse.copy(TRANSLATION_BACKUP_PATH, translationStorePath, function (err) {
if (err) {
console.error(err);
done();
return;
}
fse.remove(TRANSLATION_BACKUP_PATH, function (err) {
if (err) {
console.error(err);
}
done();
});
});
});
}

View file

@ -1,4 +1,4 @@
import { i18n } from './i18n';
import i18n from './i18n';
/*
Manages the language translations for Kibana. Responsible for loading translated content per language.

View file

@ -10,6 +10,13 @@ import UiExports from './ui_exports';
import UiBundle from './ui_bundle';
import UiBundleCollection from './ui_bundle_collection';
import UiBundlerEnv from './ui_bundler_env';
import i18nPlugin from '../plugins/i18n/server/i18n/index';
import langParser from 'accept-language-parser';
let kibanaTranslations = [];
let acceptLanguages = '';
const DEFAULT_LANGUAGE = 'en';
export default async (kbnServer, server, config) => {
const uiExports = kbnServer.uiExports = new UiExports({
@ -50,6 +57,9 @@ export default async (kbnServer, server, config) => {
const app = uiExports.apps.byId[id];
if (!app) return reply(Boom.notFound('Unknown app ' + id));
const acceptLanguageStr = req.headers['accept-language'];
acceptLanguages = langParser.parse(acceptLanguageStr);
try {
if (kbnServer.status.isGreen()) {
await reply.renderApp(app);
@ -88,6 +98,10 @@ export default async (kbnServer, server, config) => {
async function renderApp({ app, reply, includeUserProvidedConfig = true }) {
try {
if (kibanaTranslations.length <= 0) {
const language = await getTranslationLanguage(acceptLanguages);
kibanaTranslations = await i18nPlugin.getRegisteredLanguageTranslations(language);
}
return reply.view(app.templateName, {
app,
kibanaPayload: await getKibanaPayload({
@ -96,6 +110,8 @@ export default async (kbnServer, server, config) => {
includeUserProvidedConfig
}),
bundlePath: `${config.get('server.basePath')}/bundles`,
welcomeMessage: translate('CORE-WELCOME_MESSAGE'),
welcomeError: translate('CORE-WELCOME_ERROR'),
});
} catch (err) {
reply(err);
@ -118,3 +134,55 @@ export default async (kbnServer, server, config) => {
});
});
};
function translate(key) {
if (!(key in kibanaTranslations)) {
return null;
}
return kibanaTranslations[key];
}
async function getTranslationLanguage(acceptLanguages) {
let langStr = '';
let foundLang = false;
const acceptLangsLen = acceptLanguages.length;
const registeredLanguages = await i18nPlugin.getRegisteredTranslationLanguages();
for (let indx = 0; indx < acceptLangsLen; indx++) {
const language = acceptLanguages[indx];
if (language.region) {
langStr = language.code + '-' + language.region;
} else {
langStr = language.code;
}
if (registeredLanguages.indexOf(langStr) > -1) {
foundLang = true;
break;
}
}
if (foundLang) {
return langStr;
}
const regLangsLen = registeredLanguages.length;
for (let indx = 0; indx < acceptLangsLen; indx++) {
const language = acceptLanguages[indx];
langStr = language.code;
for (let regIndx = 0; regIndx < regLangsLen; regIndx++) {
const lang = registeredLanguages[regIndx];
if (lang.match('^' + langStr)) {
langStr = lang;
foundLang = true;
break;
}
}
if (foundLang) {
break;
}
}
if (foundLang) {
return langStr;
}
return DEFAULT_LANGUAGE;
}

View file

@ -125,7 +125,7 @@ block content
err.style['text-align'] = 'center';
err.style['background'] = '#F44336';
err.style['padding'] = '25px';
err.innerText = 'Kibana did not load properly. Check the server output for more information.';
err.innerText = '#{welcomeError}';
document.body.innerHTML = err.outerHTML;
}