Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can use different files for the same language? #423

Open
Degeoksz opened this issue Jan 11, 2020 · 5 comments
Open

Can use different files for the same language? #423

Degeoksz opened this issue Jan 11, 2020 · 5 comments

Comments

@Degeoksz
Copy link

Right now i'm using express and i have two files in my "locales" folder.

  • es.json
  • en.json

is there a possibility to use different files for the same language (to have a more organized files). Example:

  • es-some-type-of-content.json
  • es-other-type-of-content.json

This is the configuration used in the app.js file

i18n.configure({
  locales: ["es", "en],
  directory: __dirname + "/locales",
  defaultLocale: "es",
  cookie: "locale",
  updateFiles: false
});
@ostar0816
Copy link

Any update on this?

@mashpie
Copy link
Owner

mashpie commented Jan 23, 2020

loading from multiple sources is not (yet) supported

@Khaos66
Copy link

Khaos66 commented Feb 7, 2020

I had the same requirement.
Luckily i18n provides us with the getCatalog function.
So this is possible:

   function addLocaleFile(locale, file) {
        // get i18n catalog instance
        let catalog = i18n.getCatalog();
        if (!catalog) {
            return;
        }

        // load file
        let localeFile = fs.readFileSync(file);
        let newLocale = JSON.parse(localeFile);

        // merge existing with new locales
        catalog[locale] = catalog[locale] ? {...catalog[locale], ...newLocale } : newLocale;
    };

Make sure you call i18n.configure with your base locales first.
After that you can call the upper function as often as you need.

addLocaleFile('es', './locales/es-some-type-of-content.json');
addLocaleFile('es', './locales/es-other-type-of-content.json');

So I used this to merge a hierarchy of locales
/locales/de.json
/locales/manage/de.json
/locales/manage/users/de.json

@mashpie
Copy link
Owner

mashpie commented Jan 23, 2023

besides the solution mentioned by @Khaos66 earlier you might take a look at https://github.com/mashpie/i18n-node#some-words-on-staticcatalog-option

or

https://github.com/mashpie/i18n-node#some-words-on-staticcatalog-option

to implement your own custom storage with

@mashpie
Copy link
Owner

mashpie commented Jan 23, 2023

well it depends on your needs, but given your namespaces I'd consider the following as starting point:

files setup like so:

├── index.js
└── locales
    ├── common-en.json
    └── invoice-en.json

// common-en.json

{
  "greeting": "Hello"
}

// invoice-en.json

{
  "balance": "Balance"
}

// index.js

const fs = require('fs')
const i18n = require('i18n')

/**
 * very simple file loader treating each file as namespace
 */
const fileLoader = (locale, files) => {
  const translations = {}
  files.forEach((file) => {
    try {
      translations[file] = JSON.parse(fs.readFileSync(`./locales/${file}-${locale}.json`))
    } catch (err) {
      console.error(err);
    }
    
  })
  return translations
}

/**
 * Load translations from files
 * with each file representing a namespace
 */
i18n.configure({
  defaultLocale: 'en',
  objectNotation: true,
  updateFiles: false,
  staticCatalog: {
    en: fileLoader('en', ['common', 'invoice'])
  }
})

/**
 * debug loaded catalog
 */
console.log(i18n.getCatalog('en')) // --> { common: { greeting: 'Hello' }, invoice: { balance: 'Balance' } }

console.log(i18n.__('common.greeting')) // --> Hello
console.log(i18n.__('invoice.balance')) // --> Balance
 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants