12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import { ReactiveCache } from '/imports/reactiveCache';
- import { Meteor } from 'meteor/meteor';
- import { ReactiveVar } from 'meteor/reactive-var';
- import Translation from '/models/translation';
- import i18next from 'i18next';
- import sprintf from 'i18next-sprintf-postprocessor';
- import languages from './languages';
- const DEFAULT_NAMESPACE = 'translation';
- const DEFAULT_LANGUAGE = 'en';
- // Carefully reproduced tap:i18n API
- export const TAPi18n = {
- i18n: null,
- current: new ReactiveVar(DEFAULT_LANGUAGE),
- async init() {
- this.i18n = i18next.createInstance().use(sprintf);
- await this.i18n.init({
- fallbackLng: DEFAULT_LANGUAGE,
- cleanCode: true,
- // Show translations debug messages only when DEBUG=true
- // OLD: debug: Meteor.isDevelopment,
- debug: process.env.DEBUG,
- supportedLngs: Object.values(languages).map(({ tag }) => tag),
- ns: DEFAULT_NAMESPACE,
- defaultNs: DEFAULT_NAMESPACE,
- postProcess: ["sprintf"],
- // Default values to match tap:i18n behaviour
- interpolation: {
- prefix: '__',
- suffix: '__',
- escapeValue: false,
- },
- resources: {},
- });
- // Load the current language data
- await TAPi18n.loadLanguage(DEFAULT_LANGUAGE);
- },
- isLanguageSupported(language) {
- return Object.values(languages).some(({ tag }) => tag === language);
- },
- getSupportedLanguages() {
- return Object.values(languages).map(({ name, code, tag }) => ({ name, code, tag }));
- },
- getLanguage() {
- return this.current.get();
- },
- loadTranslation(language) {
- return new Promise((resolve, reject) => {
- if (Meteor.isClient) {
- const translationSubscription = Meteor.subscribe('translation', {language: language}, 0, {
- onReady() {
- resolve(translationSubscription);
- },
- onError(error) {
- reject(error);
- }
- });
- } else {
- resolve();
- }
- });
- },
- async loadLanguage(language) {
- if (language in languages && 'load' in languages[language]) {
- let data = await languages[language].load();
- let custom_translations = [];
- await this.loadTranslation(language);
- custom_translations = ReactiveCache.getTranslations({language: language}, {fields: { text: true, translationText: true }});
- if (custom_translations && custom_translations.length > 0) {
- data = custom_translations.reduce((acc, cur) => (acc[cur.text]=cur.translationText, acc), data);
- }
- this.i18n.addResourceBundle(language, DEFAULT_NAMESPACE, data);
- } else {
- throw new Error(`Language ${language} is not supported`);
- }
- },
- async setLanguage(language) {
- await this.loadLanguage(language);
- await this.i18n.changeLanguage(language);
- this.current.set(language);
- },
- // Return translation by key
- __(key, options, language) {
- this.current.dep.depend();
- return this.i18n.t(key, {
- ...options,
- lng: language,
- });
- }
- };
|