i18n-node icon indicating copy to clipboard operation
i18n-node copied to clipboard

possible to default at locale if definition not found

Open grd2345 opened this issue 10 years ago • 5 comments

Lets say I have two files, one called es.json and one called es_MX.json and have my common spanish definitions in es.json and my Mexico definitions in es_MX. Is it possible for i18n to grab the definitions in es.json if es_MX.json does not contain it. Currently I have to define definitions in both files, even though some will be identical, etc.

grd2345 avatar Jul 27 '15 22:07 grd2345

+1

I've been thinking about this too. https://github.com/jeresig/i18n-node-2 has an interesting base configuration option where you can define a function to redefine the locale names as needed. I had done the following when trying his package:

i18n.expressBind(app, {
  locales:['eng', 'eng-gb', 'spa', 'jpn'],
  // Use the first three characters of a locale as the "base" locale.
  // Basically, this allows an `aaa-bb` locale to get things from an `aaa` locale.
  base: function(locale) {
    return locale.slice(0,3);
  },
  defaultLocale: 'eng',
  // ...
});

However, it looks a little limited and doesn't "inherit" as I would like it to. I haven't studied the i18n-node code too much, but what about something like the following?

Start by having another configuration option where you can provide a handler function that accepts the "child" locale name and returns the "parent" local name it should inherit from. (Or perhaps, the current fallbacks option could accept an object or a function and be smart enough to handler either?) For example with the OP:

i18n.configure({
  locales:['es', 'es_MX'],
  parentLocale: function(child) {
    // Do something that returns the "parent" locale name for the given `child` locale name.
    // Given the OP example, have it return the first two characters:
    return child.slice(0,2);
  },
  // ...
});

Then when the locale catalog is loaded, it would do something like the following pseudo code:

var deepmerge = require('deepmerge');

function whateverTheFunctionIsThatLoadsTheCatalogForTheCurrentLocale(locale) {
  var parentLocale = parentLocale(locale),
      childCatalog = someFunctionThatLoadsTheJSON(locale),
      parentCatalog = someFunctionThatLoadsTheJSON(parentLocale);

  // Have "child" override any "parent" properties
  return deepmerge(parentCatalog, childCatalog);
}

Just some thoughts. I'd need to study up some more on the code base to see if this is possible. Haven't used the deepmerge package, so there may be a better solution out there.

It could even get crazy and allow recursive inheritance (e.g., "es_MZ-something" < "es_MZ" < "es").

robertwbradford avatar Feb 10 '16 18:02 robertwbradford

ok, I think one could setup such like so with fallbacks (https://github.com/mashpie/i18n-node#list-of-configuration-options):

    fallbacks: {
      'es': 'es_MZ',
      'es_MZ': 'es_MZ-something'
    },

tests don't cover that scenario at the moment (https://github.com/mashpie/i18n-node/blob/master/test/i18n.fallbacks.js). Excepting a callback in configuration of fallbacks sounds like the most flexible option.

I'll keep that in backlog for now to focus on open PRs and setLocale refactory.

mashpie avatar Feb 11 '16 09:02 mashpie

+1

simonmilz avatar Jun 23 '17 14:06 simonmilz

If I understand correctly, this is still an issue and there is no way to have fallback locales at "key" level, right? (for example, having a 'en-gb' locale which overrides just a couple of translations of 'en' locale)

jsilveira avatar Feb 06 '20 14:02 jsilveira

Yes, I'm seeing the same issue with having partial translations and not falling back to either language or default locale (even with retryInDefaultLocale: true and fallbacks).

If I have key1 defined in 'ja-JP', key2 defined in 'ja', and all keys defined under default locale: Lookup of key2 with locale 'ja-JP' is not found (returning the key / missingKeyFn), despite being defined under 'ja' and default locale. If both keys were defined only under 'ja' this would work looking up as 'ja-JP' (fallbacks 'ja-*':'ja' works, and default locale returned without fallbacks config) The partial translation breaks the fallback to lang.

matt-blanchette avatar Jun 17 '22 16:06 matt-blanchette