mirror of
https://github.com/flarum/framework.git
synced 2024-11-25 09:41:49 +08:00
87 lines
2.5 KiB
JavaScript
87 lines
2.5 KiB
JavaScript
import User from 'flarum/models/User';
|
|
import username from 'flarum/helpers/username';
|
|
import extractText from 'flarum/utils/extractText';
|
|
import extract from 'flarum/utils/extract';
|
|
|
|
/**
|
|
* The `Translator` class translates strings using the loaded localization.
|
|
*/
|
|
export default class Translator {
|
|
constructor() {
|
|
/**
|
|
* A map of translation keys to their translated values.
|
|
*
|
|
* @type {Object}
|
|
* @public
|
|
*/
|
|
this.translations = {};
|
|
}
|
|
|
|
/**
|
|
* Determine the key of a translation that should be used for the given count.
|
|
* The default implementation is for English plurals. It should be overridden
|
|
* by a locale's JavaScript file if necessary.
|
|
*
|
|
* @param {Integer} count
|
|
* @return {String}
|
|
* @public
|
|
*/
|
|
plural(count) {
|
|
return count === 1 ? 'one' : 'other';
|
|
}
|
|
|
|
/**
|
|
* Translate a string.
|
|
*
|
|
* @param {String} key
|
|
* @param {Object} input
|
|
* @param {VirtualElement} fallback
|
|
* @return {VirtualElement}
|
|
*/
|
|
trans(key, input = {}, fallback) {
|
|
const parts = key.split('.');
|
|
let translation = this.translations;
|
|
|
|
// Drill down into the translation tree to find the translation for this
|
|
// key.
|
|
parts.forEach(part => {
|
|
translation = translation && translation[part];
|
|
});
|
|
|
|
// If this translation has multiple options and a 'count' has been provided
|
|
// in the input, we'll work out which option to choose using the `plural`
|
|
// method.
|
|
if (typeof translation === 'object' && typeof input.count !== 'undefined') {
|
|
translation = translation[this.plural(extractText(input.count))];
|
|
}
|
|
|
|
// If we've been given a user model as one of the input parameters, then
|
|
// we'll extract the username and use that for the translation. In the
|
|
// future there should be a hook here to inspect the user and change the
|
|
// translation key. This will allow a gender property to determine which
|
|
// translation key is used.
|
|
if (input.user instanceof User) {
|
|
const user = extract(input, 'user');
|
|
|
|
if (!input.username) input.username = username(user);
|
|
}
|
|
|
|
// If we've found the appropriate translation string, then we'll sub in the
|
|
// input.
|
|
if (typeof translation === 'string') {
|
|
translation = translation.split(new RegExp('({[^}]+})', 'gi'));
|
|
|
|
translation.forEach((part, i) => {
|
|
const match = part.match(/^{(.+)}$/i);
|
|
if (match) {
|
|
translation[i] = input[match[1]];
|
|
}
|
|
});
|
|
|
|
return translation;
|
|
}
|
|
|
|
return fallback || [key];
|
|
}
|
|
}
|