From 61c7bb96994cc7f987fa7702a72edf38e713af34 Mon Sep 17 00:00:00 2001 From: Daniel Krol Date: Tue, 19 May 2020 08:21:31 -0400 Subject: [PATCH] feat(i18n) Custom i18n strings (#4000) * Custom i18n strings (and some code formatting) * Documentation for per-instance l10n overwrites --- doc/localization.md | 20 ++++++++++++++++++++ settings.json.docker | 5 ++++- settings.json.template | 5 ++++- src/node/hooks/express/adminsettings.js | 4 ++-- src/node/hooks/i18n.js | 19 ++++++++++++++++++- src/node/utils/Settings.js | 5 +++++ src/templates/admin/index.html | 2 +- 7 files changed, 54 insertions(+), 6 deletions(-) diff --git a/doc/localization.md b/doc/localization.md index ba247ea3..c94a680b 100644 --- a/doc/localization.md +++ b/doc/localization.md @@ -92,3 +92,23 @@ For example, if you want to replace `Chat` with `Notes`, simply add... , "pad.chat": "Notes" } ``` + +## Customization for Administrators + +As an Etherpad administrator, it is possible to overwrite core mesages as well as messages in plugins. These include error messages, labels, and user instructions. Whereas the localization in the source code is in separate files separated by locale, an administrator's custom localizations are in `settings.json` under the `customLocaleStrigns` key, with each locale separated by a sub-key underneath. + +For example, let's say you want to change the text on the "New Pad" button on Etherpad's home page. If you look in `locales/en.json` (or `locales/en-gb.json`) you'll see the key for this text is `"index.newPad"`. You could add the following to `settings.json`: + +``` + "customLocaleStrings": { + "fr": { + "index.newPad": "Créer un document" + }, + "en-gb": { + "index.newPad": "Create a document" + }, + "en": { + "index.newPad": "Create a document" + } + } +``` diff --git a/settings.json.docker b/settings.json.docker index 2f2d0092..332e06ac 100644 --- a/settings.json.docker +++ b/settings.json.docker @@ -551,5 +551,8 @@ */ ] - } // logconfig + }, // logconfig + + /* Override any strings found in locale directories */ + "customLocaleStrings": {} } diff --git a/settings.json.template b/settings.json.template index f01dc780..27f1fb60 100644 --- a/settings.json.template +++ b/settings.json.template @@ -556,5 +556,8 @@ */ ] - } // logconfig + }, // logconfig + + /* Override any strings found in locale directories */ + "customLocaleStrings": {} } diff --git a/src/node/hooks/express/adminsettings.js b/src/node/hooks/express/adminsettings.js index baa0bb70..1e0d6004 100644 --- a/src/node/hooks/express/adminsettings.js +++ b/src/node/hooks/express/adminsettings.js @@ -29,9 +29,9 @@ exports.socketio = function (hook_name, args, cb) { return console.log(err); } - //if showSettingsInAdminPage is set to false, then return NOT_ALLOWED in the result + // if showSettingsInAdminPage is set to false, then return NOT_ALLOWED in the result if(settings.showSettingsInAdminPage === false) { - socket.emit("settings", {results:'NOT_ALLOWED'}); + socket.emit("settings", {results: 'NOT_ALLOWED'}); } else { socket.emit("settings", {results: data}); diff --git a/src/node/hooks/i18n.js b/src/node/hooks/i18n.js index 122efdd3..736372ed 100644 --- a/src/node/hooks/i18n.js +++ b/src/node/hooks/i18n.js @@ -6,6 +6,7 @@ var languages = require('languages4translatewiki') , plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins.js').plugins , semver = require('semver') , existsSync = require('../utils/path_exists') + , settings = require('../utils/Settings'); ; @@ -43,7 +44,7 @@ function getAllLocales() { //add plugins languages (if any) for(var pluginName in plugins) extractLangs(path.join(npm.root, pluginName, 'locales')); - // Build a locale index (merge all locale data) + // Build a locale index (merge all locale data other than user-supplied overrides) var locales = {} _.each (locales2paths, function(files, langcode) { locales[langcode]={}; @@ -54,6 +55,22 @@ function getAllLocales() { }); }); + // Add custom strings from settings.json + // Since this is user-supplied, we'll do some extra sanity checks + const wrongFormatErr = Error( + "customLocaleStrings in wrong format. See documentation " + + "for Customization for Administrators, under Localization.") + if (settings.customLocaleStrings) { + if (typeof settings.customLocaleStrings !== "object") throw wrongFormatErr + _.each(settings.customLocaleStrings, function(overrides, langcode) { + if (typeof overrides !== "object") throw wrongFormatErr + _.each(overrides, function(localeString, key) { + if (typeof localeString !== "string") throw wrongFormatErr + locales[langcode][key] = localeString + }) + }) + } + return locales; } diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js index c8f2ec15..0dcd05ea 100644 --- a/src/node/utils/Settings.js +++ b/src/node/utils/Settings.js @@ -321,6 +321,11 @@ exports.scrollWhenFocusLineIsOutOfViewport = { */ exports.exposeVersion = false; +/* + * Override any strings found in locale directories + */ +exports.customLocaleStrings = {}; + /* * From Etherpad 1.8.3 onwards, import and export of pads is always rate * limited. diff --git a/src/templates/admin/index.html b/src/templates/admin/index.html index 45755a49..01724f50 100644 --- a/src/templates/admin/index.html +++ b/src/templates/admin/index.html @@ -12,7 +12,7 @@