vazco / meteor-universe-i18n

Internationalization package for Meteor with React integration.
https://atmospherejs.com/universe/i18n
MIT License
123 stars 32 forks source link

Adding translations to the universe:i18n package at runtime #82

Closed Subjekt2Change closed 6 years ago

Subjekt2Change commented 7 years ago

Please bear with me if this question sounds stupid, i have just begun working with react and am thus a greenhorn.

I am currently working on a system which should allow translators to create new translation files with already existing ones as templates. Additionally translators should be able to change existing translations in the back-end.

As far as i have understood all translation files are packed into the universe:i18n package. So i reckon adding / changing files in the /i18n/ folder via the node fileSystem (as i'm doing it now) would not have any effect once the project is complete.

My question is as follows: Is it possible to add / change translations inside the package at runtime? If it is not possible can i cheat this by saving the files on another host?

I have already tried changing translations using the i18n.addTranslation command but sadly these are resetted after a reload.

cristo-rabani commented 7 years ago

Hello @Subjekt2Change

There are a few possibilities depending on what you want to do. Example Solutions:

  1. Any client can get translations form remotely server which potentially can be not own. in option you can find hostUrl: 'http://current.host.url/', example: http://localhost:3000/universe/locale/en which en is you locale So, you can change server for tanslations

  2. Server side solution can look like:

    
    import i18n from 'meteor/universe:i18n';
    import {UniUtils} from 'meteor/universe:utilities';

const {getJS, getJSON, getYML} = i18n._formatgetters; const cache = i18n.getCache(); Meteor.startup(() => { YourCollection.find({}, {fields: {updatedAt: 1}, transform: null}).observeChanges({ added: refreshTranslations, changed: refreshTranslations }); }); function refreshTranslations (locale, {updatedAt}) { locale = i18n._normalize(locale); const {_id, translations = {}} = YourCollection.findOne(locale) || {}; if (!i18n._translations[locale]) { i18n._translations[locale] = {}; } if (_id) { for(let {path, node} of new UniUtils.RecursiveIterator(translations)) { if (typeof node === 'string') { UniUtils.set(i18n._translations[locale], path.join('.'), node); }

    }
    cache[locale] = {
        updatedAt,
        getYML,
        getJSON,
        getJS
    };
    i18n._emitChange(locale);
    UniConfig.public.set('i18n_last_cache_refreshed', Date.now(),  true);
}

}

export const saveTranslations = (locale, paths, text) => { if (!text) { return new Date(); } locale = i18n.normalize(locale); const {translations = {}} = YourCollection.findOne(locale) || {}; UniUtils.set(translations, paths, text); const date = new Date(); YourCollection.upsert({_id: locale}, {updatedAt: date, 'translations': translations}); return date; };

jasongrishkoff commented 5 years ago

Worth noting that under refreshTranslations there's a line that says locale = i18n._normalize(locale); -- I believe the underscore should be removed so it's just locale = i18n.normalize(locale);