in modules/core/localizer.js [243:344]
localizer.tInfo = function(origStringId, replacements, locale) {
let stringId = origStringId.trim();
let scopeId = 'general';
if (stringId[0] === '_') {
let split = stringId.split('.');
scopeId = split[0].slice(1);
stringId = split.slice(1).join('.');
}
locale = locale || _localeCode;
let path = stringId
.split('.')
.map(s => s.replace(/<TX_DOT>/g, '.'))
.reverse();
let stringsKey = locale;
// US English is the default
if (stringsKey.toLowerCase() === 'en-us') stringsKey = 'en';
let result = _localeStrings && _localeStrings[scopeId] && _localeStrings[scopeId][stringsKey];
while (result !== undefined && path.length) {
result = result[path.pop()];
}
if (result !== undefined) {
if (replacements) {
if (typeof result === 'object' && Object.keys(result).length) {
// If plural forms are provided, dig one level deeper based on the
// first numeric token replacement provided.
const number = Object.values(replacements).find(function(value) {
return typeof value === 'number';
});
if (number !== undefined) {
const rule = pluralRule(number, locale);
if (result[rule]) {
result = result[rule];
} else {
// We're pretty sure this should be a plural but no string
// could be found for the given rule. Just pick the first
// string and hope it makes sense.
result = Object.values(result)[0];
}
}
}
if (typeof result === 'string') {
for (let key in replacements) {
let value = replacements[key];
if (typeof value === 'number') {
if (value.toLocaleString) {
// format numbers for the locale
value = value.toLocaleString(locale, {
style: 'decimal',
useGrouping: true,
minimumFractionDigits: 0
});
} else {
value = value.toString();
}
}
const token = `{${key}}`;
const regex = new RegExp(token, 'g');
result = result.replace(regex, value);
}
}
}
if (typeof result === 'string') {
// found a localized string!
return {
text: result,
locale: locale
};
}
}
// no localized string found...
// attempt to fallback to a lower-priority language
let index = _localeCodes.indexOf(locale);
if (index >= 0 && index < _localeCodes.length - 1) {
// eventually this will be 'en' or another locale with 100% coverage
let fallback = _localeCodes[index + 1];
return localizer.tInfo(origStringId, replacements, fallback);
}
if (replacements && 'default' in replacements) {
// Fallback to a default value if one is specified in `replacements`
return {
text: replacements.default,
locale: null
};
}
const missing = `Missing ${locale} translation: ${origStringId}`;
if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line
return {
text: missing,
locale: 'en'
};
};