7

I'm using I18Next as a Javascript-based Translation Solution, and here's what needs to happen:

  1. A default namespace "Core" is loaded. It contains most keys I want, but not all of them.
  2. There is no fixed list of namespaces: hence I cannot just tell i18n.init the ns.namespaces I want.
  3. During the pageload, optionally some "Modules" are loaded into the Application and they also need to be translated. They should report their i18n namespace name somewhere, and then i18n shuold make that namespace's keys available.

Basically, is there a way for i18next to autoload namespaces as they are called? It is guaranteed that the namespaces that are called through t("[SomeNamespace]Key.Key2"); are valid and certainly exist. The issue is simply that i18next cannot "autoload" and I am unable to find a way to make i18n "manually" load a resource file after i18n.init has been called.

Here's my current code.

    $.i18n.init(
        {
            lng: "en",
            fallbackLng: "en",
            useCookie: false,
            resGetPath: "System/i18n/__ns__/__lng__.json",
            ns: "Core"
        },
        function(t) {
            System.I18N = t;

            alert(System.I18N("LoginUI:Messages.Name"));
        }
    );

As expected, it simply shows me LoginUI:Messages.Name instead of the translation in System/i18n/LoginUI/en.json:

{
    "Messages": {
        "Name": "Logon Interface"
    }
}

(Core/en.json is irrelevant in this case. All I currently need is "LoginUI/en.json" to be autoloaded or I can force a manual loading.)

Jimmie Lin
  • 2,205
  • 2
  • 23
  • 35

2 Answers2

3

i18next comes now with a function to load additional namespaces after initialization: https://www.i18next.com/principles/namespaces#sample

Stephane
  • 11,056
  • 9
  • 41
  • 51
jamuhl
  • 4,352
  • 2
  • 25
  • 31
  • this doesn't address the OP problem, i mean, as far I as understood, the OP is looking for something that translates `i18next.t('key',{ ns : namespaceFoo })` loading "on demand" the namespaceFoo.. I know that the former example could be impossible because the it would turn to be a promise as return value, because it may have to fetch the translations as an external resource. I'm trying and struggling finding a way to perform it adding the less burden in terms of maintenance and expansion. As the way I see this problem it is intrinsic to web browser navigation affairs, UI related. – Victor Sep 29 '22 at 23:08
2

After some digging into the source code, I've created a solution that sort-of works, but certainly requires improving in the long term.

Within i18n.addjQueryFunct()'s definition, add this to access resStore (the translation storage variable):

$.i18n._getResStore = _getResStore;
$.i18n._writeResStore = _writeResStore;

function _getResStore() {
    return resStore;
}

function _writeResStore(r) {
    resStore = r;
}

When you want to load an extra namespace, simply do something like this:

// define options, run $.i18n.init, etc...
// suppose ns = "namespace_foobar_new"
options.ns.namespaces.push(ns);
$.i18n.sync._fetchOne(lang, ns, $.extend({}, $.i18n.options, options),
    function(err, data) {
    store = {};
        store[lang] = {}; store[lang][ns] = data;

            newResStore = $.extend(true, {}, $.i18n._getResStore(), store);
            $.i18n._writeResStore(newResStore);
    });

Phew.

Jimmie Lin
  • 2,205
  • 2
  • 23
  • 35
  • 1
    As loading resources works by default async autoloading isn't that simple to implement. but you can add the new namespace to your config, which you use to init i18next with and just reinit it. Might not be the nicest solution...just add a request on github for such a feature...will add such a feature for next release. – jamuhl Nov 13 '12 at 01:22