mirror of
				https://github.com/MichMich/MagicMirror.git
				synced 2025-10-31 02:36:47 +00:00 
			
		
		
		
	Before: ``` MMM-OlympicGames - Load translationfalse: translations/de.json translator.js:107 MMM-OlympicGames - Load translation fallback: translations/en.json ``` After: ``` MMM-OlympicGames - Load translation: translations/de.json translator.js:107 MMM-OlympicGames - Load translation fallback: translations/en.json ```
		
			
				
	
	
		
			156 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* global translations */
 | |
| 
 | |
| /* MagicMirror²
 | |
|  * Translator (l10n)
 | |
|  *
 | |
|  * By Christopher Fenner https://github.com/CFenner
 | |
|  * MIT Licensed.
 | |
|  */
 | |
| const Translator = (function () {
 | |
| 	/**
 | |
| 	 * Load a JSON file via XHR.
 | |
| 	 *
 | |
| 	 * @param {string} file Path of the file we want to load.
 | |
| 	 * @param {Function} callback Function called when done.
 | |
| 	 */
 | |
| 	function loadJSON(file, callback) {
 | |
| 		const xhr = new XMLHttpRequest();
 | |
| 		xhr.overrideMimeType("application/json");
 | |
| 		xhr.open("GET", file, true);
 | |
| 		xhr.onreadystatechange = function () {
 | |
| 			if (xhr.readyState === 4 && xhr.status === 200) {
 | |
| 				// needs error handler try/catch at least
 | |
| 				let fileinfo = null;
 | |
| 				try {
 | |
| 					fileinfo = JSON.parse(xhr.responseText);
 | |
| 				} catch (exception) {
 | |
| 					// nothing here, but don't die
 | |
| 					Log.error(" loading json file =" + file + " failed");
 | |
| 				}
 | |
| 				callback(fileinfo);
 | |
| 			}
 | |
| 		};
 | |
| 		xhr.send(null);
 | |
| 	}
 | |
| 
 | |
| 	return {
 | |
| 		coreTranslations: {},
 | |
| 		coreTranslationsFallback: {},
 | |
| 		translations: {},
 | |
| 		translationsFallback: {},
 | |
| 
 | |
| 		/**
 | |
| 		 * Load a translation for a given key for a given module.
 | |
| 		 *
 | |
| 		 * @param {Module} module The module to load the translation for.
 | |
| 		 * @param {string} key The key of the text to translate.
 | |
| 		 * @param {object} variables The variables to use within the translation template (optional)
 | |
| 		 * @returns {string} the translated key
 | |
| 		 */
 | |
| 		translate: function (module, key, variables) {
 | |
| 			variables = variables || {}; //Empty object by default
 | |
| 
 | |
| 			/**
 | |
| 			 * Combines template and variables like:
 | |
| 			 * template: "Please wait for {timeToWait} before continuing with {work}."
 | |
| 			 * variables: {timeToWait: "2 hours", work: "painting"}
 | |
| 			 * to: "Please wait for 2 hours before continuing with painting."
 | |
| 			 *
 | |
| 			 * @param {string} template Text with placeholder
 | |
| 			 * @param {object} variables Variables for the placeholder
 | |
| 			 * @returns {string} the template filled with the variables
 | |
| 			 */
 | |
| 			function createStringFromTemplate(template, variables) {
 | |
| 				if (Object.prototype.toString.call(template) !== "[object String]") {
 | |
| 					return template;
 | |
| 				}
 | |
| 				if (variables.fallback && !template.match(new RegExp("{.+}"))) {
 | |
| 					template = variables.fallback;
 | |
| 				}
 | |
| 				return template.replace(new RegExp("{([^}]+)}", "g"), function (_unused, varName) {
 | |
| 					return varName in variables ? variables[varName] : "{" + varName + "}";
 | |
| 				});
 | |
| 			}
 | |
| 
 | |
| 			if (this.translations[module.name] && key in this.translations[module.name]) {
 | |
| 				// Log.log("Got translation for " + key + " from module translation: ");
 | |
| 				return createStringFromTemplate(this.translations[module.name][key], variables);
 | |
| 			}
 | |
| 
 | |
| 			if (key in this.coreTranslations) {
 | |
| 				// Log.log("Got translation for " + key + " from core translation.");
 | |
| 				return createStringFromTemplate(this.coreTranslations[key], variables);
 | |
| 			}
 | |
| 
 | |
| 			if (this.translationsFallback[module.name] && key in this.translationsFallback[module.name]) {
 | |
| 				// Log.log("Got translation for " + key + " from module translation fallback.");
 | |
| 				return createStringFromTemplate(this.translationsFallback[module.name][key], variables);
 | |
| 			}
 | |
| 
 | |
| 			if (key in this.coreTranslationsFallback) {
 | |
| 				// Log.log("Got translation for " + key + " from core translation fallback.");
 | |
| 				return createStringFromTemplate(this.coreTranslationsFallback[key], variables);
 | |
| 			}
 | |
| 
 | |
| 			return key;
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Load a translation file (json) and remember the data.
 | |
| 		 *
 | |
| 		 * @param {Module} module The module to load the translation file for.
 | |
| 		 * @param {string} file Path of the file we want to load.
 | |
| 		 * @param {boolean} isFallback Flag to indicate fallback translations.
 | |
| 		 * @param {Function} callback Function called when done.
 | |
| 		 */
 | |
| 		load(module, file, isFallback, callback) {
 | |
| 			Log.log(`${module.name} - Load translation${isFallback ? " fallback" : ""}: ${file}`);
 | |
| 
 | |
| 			if (this.translationsFallback[module.name]) {
 | |
| 				callback();
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
| 			loadJSON(module.file(file), (json) => {
 | |
| 				const property = isFallback ? "translationsFallback" : "translations";
 | |
| 				this[property][module.name] = json;
 | |
| 				callback();
 | |
| 			});
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Load the core translations.
 | |
| 		 *
 | |
| 		 * @param {string} lang The language identifier of the core language.
 | |
| 		 */
 | |
| 		loadCoreTranslations: function (lang) {
 | |
| 			if (lang in translations) {
 | |
| 				Log.log("Loading core translation file: " + translations[lang]);
 | |
| 				loadJSON(translations[lang], (translations) => {
 | |
| 					this.coreTranslations = translations;
 | |
| 				});
 | |
| 			} else {
 | |
| 				Log.log("Configured language not found in core translations.");
 | |
| 			}
 | |
| 
 | |
| 			this.loadCoreTranslationsFallback();
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Load the core translations fallback.
 | |
| 		 * The first language defined in translations.js will be used.
 | |
| 		 */
 | |
| 		loadCoreTranslationsFallback: function () {
 | |
| 			let first = Object.keys(translations)[0];
 | |
| 			if (first) {
 | |
| 				Log.log("Loading core translation fallback file: " + translations[first]);
 | |
| 				loadJSON(translations[first], (translations) => {
 | |
| 					this.coreTranslationsFallback = translations;
 | |
| 				});
 | |
| 			}
 | |
| 		}
 | |
| 	};
 | |
| })();
 | |
| 
 | |
| window.Translator = Translator;
 |