From 618568e09f8c902c6b99a7faf55efeacf1210da2 Mon Sep 17 00:00:00 2001
From: Christoph Reiter <reiter.christoph@gmail.com>
Date: Thu, 10 Jun 2021 11:58:00 +0200
Subject: [PATCH] language-select: add a small demo for how to override
 translations at runtime

Uses a separate namespace that gets used over the default one, so we can override,
but also remove the overrides again when needed.

This has the problem that all clones have the same store, so this overrides
the translations for all clones and not just the one providing the overrides.
---
 packages/common/i18next.js                    | 11 +++++-
 .../src/dbp-language-select-demo.js           | 38 ++++++++++++++++++-
 .../src/i18n/de/translation.json              |  3 +-
 .../src/i18n/en/translation.json              |  3 +-
 4 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/packages/common/i18next.js b/packages/common/i18next.js
index 22f445cb..26d78a3f 100644
--- a/packages/common/i18next.js
+++ b/packages/common/i18next.js
@@ -50,19 +50,26 @@ export function humanFileSize(bytes, si = false) {
  * @param {object} languages - Mapping from languages to translation objects
  * @param {string} lng - The default language
  * @param {string} fallback - The fallback language to use for unknown languages or untranslated keys
+ * @param {string} [namespace] - The i18next namespace to load, defaults to 'translation'
  * @returns {i18next.i18n} A new independent i18next instance
  */
-export function createInstance(languages, lng, fallback) {
+export function createInstance(languages, lng, fallback, namespace) {
+    if (namespace === undefined)
+        namespace = 'translation';
+
     var options = {
         lng: lng,
         fallbackLng: fallback,
         debug: false,
+        ns: [namespace + '-override'],
+        defaultNS: namespace + '-override',
+        fallbackNS: [namespace],
         initImmediate: false, // Don't init async
         resources: {},
     };
 
     Object.keys(languages).forEach(function(key) {
-        options['resources'][key] = {translation: languages[key]};
+        options['resources'][key] = {[namespace]: languages[key]};
     });
 
     var i18n = i18next.createInstance();
diff --git a/packages/language-select/src/dbp-language-select-demo.js b/packages/language-select/src/dbp-language-select-demo.js
index 8a303139..2bbf7395 100644
--- a/packages/language-select/src/dbp-language-select-demo.js
+++ b/packages/language-select/src/dbp-language-select-demo.js
@@ -4,13 +4,39 @@ import * as commonUtils from '@dbp-toolkit/common/utils';
 import { ScopedElementsMixin } from '@open-wc/scoped-elements';
 import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element";
 import {Provider} from "@dbp-toolkit/provider";
+import {i18n} from './i18n.js';
 
+// This is an example on how to override translations at runtime
+let OVERRIDES = {
+    'de': {
+        'translation': {
+            'demo': 'Ãœberschrieben'
+        }
+    },
+    'en': {
+        'translation': {
+            'demo': 'Overridden'
+        }
+    }
+};
+
+function applyOverrides(i18n, namespace, overrides) {
+    for(let lang of Object.keys(overrides)) {
+        let data = overrides[lang][namespace];
+        if (data !== undefined) {
+            i18n.addResourceBundle(lang, namespace + '-override', data);
+        }
+    }
+}
 
 class LanguageSelectDisplay extends AdapterLitElement {
 
     constructor() {
         super();
         this.lang = 'de';
+        this._i18n = i18n.cloneInstance();
+        // FIXME: this overrides the translations for all clones
+        applyOverrides(this._i18n, 'translation', OVERRIDES);
     }
 
     static get properties() {
@@ -19,8 +45,18 @@ class LanguageSelectDisplay extends AdapterLitElement {
         };
     }
 
+    update(changedProperties) {
+        changedProperties.forEach((oldValue, propName) => {
+            switch (propName) {
+                case 'lang':
+                    this._i18n.changeLanguage(this.lang);
+            }
+        });
+        super.update(changedProperties);
+    }
+
     render() {
-        return html`${this.lang}`;
+        return html`<b>${this.lang}: ${this._i18n.t('demo')}</b>`;
     }
 }
 
diff --git a/packages/language-select/src/i18n/de/translation.json b/packages/language-select/src/i18n/de/translation.json
index 62536512..f19ffd1c 100644
--- a/packages/language-select/src/i18n/de/translation.json
+++ b/packages/language-select/src/i18n/de/translation.json
@@ -2,5 +2,6 @@
   "de": "Deutsch",
   "en": "Englisch",
   "de-action": "Auf Deutsch anzeigen",
-  "en-action": "Auf Englisch anzeigen"
+  "en-action": "Auf Englisch anzeigen",
+  "demo": "Hallo Welt"
 }
diff --git a/packages/language-select/src/i18n/en/translation.json b/packages/language-select/src/i18n/en/translation.json
index 1177302e..52ba2b38 100644
--- a/packages/language-select/src/i18n/en/translation.json
+++ b/packages/language-select/src/i18n/en/translation.json
@@ -2,5 +2,6 @@
   "de": "German",
   "en": "English",
   "de-action": "Switch to German",
-  "en-action": "Switch to English"
+  "en-action": "Switch to English",
+  "demo": "Hello World"
 }
-- 
GitLab