MOBILE-2333 siteaddons: Support lang and fix custom strings

main
Dani Palou 2018-02-14 12:39:19 +01:00
parent 5cb8437936
commit 3f5ba683ef
2 changed files with 122 additions and 98 deletions

View File

@ -105,6 +105,20 @@ export class CoreSiteAddonsProvider {
return this.ROOT_CACHE_KEY + 'content:' + component + ':' + method + ':' + JSON.stringify(args);
}
/**
* Given a handler's unique name, return the prefix to add to its string keys.
*
* @param {string} handlerName Handler's unique name (result of getHandlerUniqueName).
* @return {string} Prefix.
*/
protected getHandlerPrefixForStrings(handlerName: string): string {
if (handlerName) {
return 'addon.' + handlerName + '.';
}
return '';
}
/**
* Given a handler's unique name and the key of a string, return the full string key (prefixed).
*
@ -113,11 +127,7 @@ export class CoreSiteAddonsProvider {
* @return {string} Full string key.
*/
protected getHandlerPrefixedString(handlerName: string, key: string): string {
if (name) {
return 'addon.' + handlerName + '.' + key;
}
return '';
return this.getHandlerPrefixForStrings(handlerName) + key;
}
/**
@ -181,6 +191,25 @@ export class CoreSiteAddonsProvider {
return false;
}
/**
* Load the lang strings for a handler.
*
* @param {any} addon Data of the addon.
* @param {string} handlerName Name of the handler in the addon.
* @param {any} handlerSchema Data about the handler.
*/
loadHandlerLangStrings(addon: any, handlerName: string, handlerSchema: any): void {
if (!handlerSchema.lang) {
return;
}
for (const lang in handlerSchema.lang) {
const prefix = this.getHandlerPrefixForStrings(this.getHandlerUniqueName(addon, handlerName));
this.langProvider.addSiteAddonsStrings(lang, handlerSchema.lang[lang], prefix);
}
}
/**
* Load a site addon.
*
@ -209,6 +238,8 @@ export class CoreSiteAddonsProvider {
* @param {any} handlerSchema Data about the handler.
*/
registerHandler(addon: any, handlerName: string, handlerSchema: any): void {
this.loadHandlerLangStrings(addon, handlerName, handlerSchema);
switch (handlerSchema.delegate) {
case 'CoreMainMenuDelegate':
this.registerMainMenuHandler(addon, handlerName, handlerSchema);

View File

@ -28,8 +28,9 @@ import { Observable } from 'rxjs';
export class CoreLangProvider {
protected fallbackLanguage = CoreConfigConstants.default_lang || 'en';
protected currentLanguage: string; // Save current language in a variable to speed up the get function.
protected customStrings = {};
protected customStrings = {}; // Strings defined using the admin tool.
protected customStringsRaw: string;
protected siteAddonsStrings = {}; // Strings defined by site addons.
constructor(private translate: TranslateService, private configProvider: CoreConfigProvider, platform: Platform,
private globalization: Globalization) {
@ -43,8 +44,47 @@ export class CoreLangProvider {
moment.locale(language);
});
});
}
this.decorateTranslate();
/**
* Add a set of site addons strings for a certain language.
*
* @param {string} lang The language where to add the strings.
* @param {any} strings Object with the strings to add.
* @param {string} [prefix] A prefix to add to all keys.
*/
addSiteAddonsStrings(lang: string, strings: any, prefix?: string): void {
// Initialize structures if they don't exist.
if (!this.siteAddonsStrings[lang]) {
this.siteAddonsStrings[lang] = {};
}
if (!this.translate.translations[lang]) {
this.translate.translations[lang] = {};
}
for (const key in strings) {
const prefixedKey = prefix + key,
value = strings[key];
if (this.customStrings[lang] && this.customStrings[lang][prefixedKey]) {
// This string is overridden by a custom string, ignore it.
continue;
}
if (!this.siteAddonsStrings[lang][prefixedKey]) {
// It's a new site addon string. Store the original value.
this.siteAddonsStrings[lang][prefixedKey] = {
original: this.translate.translations[lang][prefixedKey],
value: value
};
} else {
// Site addon string already defined. Store the new value.
this.siteAddonsStrings[lang][prefixedKey].value = value;
}
// Store the string in the translations table.
this.translate.translations[lang][prefixedKey] = value;
}
}
/**
@ -69,51 +109,17 @@ export class CoreLangProvider {
* Clear current custom strings.
*/
clearCustomStrings(): void {
this.unloadStrings(this.customStrings);
this.customStrings = {};
this.customStringsRaw = '';
}
/**
* Function to "decorate" the TranslateService.
* Basically, it extends the translate functions to use the custom lang strings.
* Clear current site addons strings.
*/
decorateTranslate(): void {
const originalGet = this.translate.get,
originalInstant = this.translate.instant;
// Redefine translate.get.
this.translate.get = (key: string | string[], interpolateParams?: object): Observable<any> => {
// Always call the original get function to avoid having to create our own Observables.
if (typeof key == 'string') {
const value = this.getCustomString(key);
if (typeof value != 'undefined') {
key = value;
}
} else {
key = this.getCustomStrings(key).translations;
}
return originalGet.apply(this.translate, [key, interpolateParams]);
};
// Redefine translate.instant.
this.translate.instant = (key: string | string[], interpolateParams?: object): any => {
if (typeof key == 'string') {
const value = this.getCustomString(key);
if (typeof value != 'undefined') {
return value;
}
return originalInstant.apply(this.translate, [key, interpolateParams]);
} else {
const result = this.getCustomStrings(key);
if (result.allFound) {
return result.translations;
}
return originalInstant.apply(this.translate, [result.translations]);
}
};
clearSiteAddonsStrings(): void {
this.unloadStrings(this.siteAddonsStrings);
this.siteAddonsStrings = {};
}
/**
@ -125,6 +131,15 @@ export class CoreLangProvider {
return this.customStrings;
}
/**
* Get all current site addons strings.
*
* @return {any} Site addons strings.
*/
getAllSiteAddonsStrings(): any {
return this.siteAddonsStrings;
}
/**
* Get current language.
*
@ -174,57 +189,6 @@ export class CoreLangProvider {
});
}
/**
* Get a custom string for a certain key.
*
* @param {string} key The key of the translation to get.
* @return {string} Translation, undefined if not found.
*/
getCustomString(key: string): string {
const customStrings = this.getCustomStringsForLanguage();
if (customStrings && typeof customStrings[key] != 'undefined') {
return customStrings[key];
}
}
/**
* Get custom strings for several keys.
*
* @param {string[]} keys The keys of the translations to get.
* @return {any} Object with translations and a boolean indicating if all translations were found in custom strings.
*/
getCustomStrings(keys: string[]): any {
const customStrings = this.getCustomStringsForLanguage(),
translations = [];
let allFound = true;
keys.forEach((key: string) => {
if (customStrings && typeof customStrings[key] != 'undefined') {
translations.push(customStrings[key]);
} else {
allFound = false;
translations.push(key);
}
});
return {
allFound: allFound,
translations: translations
};
}
/**
* Get custom strings for a certain language.
*
* @param {string} [lang] The language to get. If not defined, return current language.
* @return {any} Custom strings.
*/
getCustomStringsForLanguage(lang?: string): any {
lang = lang || this.currentLanguage;
return this.customStrings[lang];
}
/**
* Load certain custom strings.
*
@ -259,7 +223,36 @@ export class CoreLangProvider {
this.customStrings[lang] = {};
}
this.customStrings[lang][values[0]] = values[1];
// Store the original value of the custom string.
this.customStrings[lang][values[0]] = {
original: this.translate.translations[lang][values[0]],
value: values[1]
};
// Store the string in the translations table.
this.translate.translations[lang][values[0]] = values[1];
});
}
/**
* Unload custom or site addon strings, removing the to the translations table.
*
* @param {any} strings Strings to unload.
*/
protected unloadStrings(strings: any): void {
// Iterate over all languages and strings.
for (const lang in strings) {
const langStrings = strings[lang];
for (const key in langStrings) {
const entry = langStrings[key];
if (entry.original) {
// The string had a value, restore it.
this.translate.translations[lang][key] = entry.original;
} else {
// The string didn't exist, delete it.
delete this.translate.translations[lang][key];
}
}
}
}
}