Git Product home page Git Product logo

i18next's Introduction

i18next: learn once - translate everywhere Tweet

CI Code Climate Coveralls Package Quality cdnjs version npm version npm

i18next is a very popular internationalization framework for browser or any other javascript environment (eg. Node.js, Deno).

ecosystem

i18next provides:

For more information visit the website:

Our focus is providing the core to building a booming ecosystem. Independent of the building blocks you choose, be it react, angular or even good old jquery proper translation capabilities are just one step away.

Documentation

The general i18next documentation is published on www.i18next.com and PR changes can be supplied here.

The react specific documentation is published on react.i18next.com and PR changes can be supplied here.


Gold Sponsors


From the creators of i18next: localization as a service - locize.com

A translation management system built around the i18next ecosystem - locize.com.

locize

With using locize you directly support the future of i18next.


i18next's People

Contributors

abepark01 avatar adrai avatar anderslemke avatar ashkyd avatar coderstefan avatar dpehrson avatar elindorath avatar gotos avatar greenkeeperio-bot avatar hugojosefson avatar huntharo avatar jamuhl avatar jantrotnow avatar jessehouchins avatar leonarddrs avatar marcalexiei avatar markdon avatar mimecuvalo avatar mjbcopland avatar namoscato avatar nburoojy avatar ossdev07 avatar pedrodurek avatar peterdavehello avatar raccoonback avatar rosskevin avatar stephenldecker avatar strajk avatar strassl avatar tkow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

i18next's Issues

Are multiple init call required?

I'm using Backbone.js and require.js. I think I might be misunderstanding something, and I think others might run into the same issue, so I am here to ask for clarification.

Do i have to call init() on i18next each time I want to use it? It seems to me that with a modular design, I should only have to initialize it once.

in an app.js file:

define([ 'jquery', 'underscore', 'backbone', 'router', 'i18n' 
], function($, _, Backbone, Router, i18n) {
    var initialize = function() {
        // Pass in our Router module and call it's initialize function
        Router.initialize();
        // localization initialization.
        var option = { 
                debug: true,
                    load: 'current',
                    ns: 'resource',
                    fallbackLng: false
                };
        i18n.init(option);
    };
    return {
        initialize : initialize
    };
});

At this point, I would assume that i18next is initialized. Now, in a view that I'm loading

define([ 'jquery', 'underscore', 'backbone', 'i18n','text!templates/login/login.html' ], 
       function($, _, Backbone,  I18N, loginTemplate) {
    var loginView = Backbone.View.extend({
        el : $("#page"),
        initialize : function() {
        },
        render : function() {
            var data = {
                _ : _
            };
            var compiledTemplate = _.template(loginTemplate, data);
            $("#page").html(compiledTemplate);

// Why do I have to init again?  (yes, this is i18n and not i18N as passed in)
                    var option = { 
                    debug: true,
                        load: 'current',
                        ns: 'resource',
                        fallbackLng: false
                    };

            I18N.init(option, function(t) {
                $("#page").i18n(); 
            });

// I would really like to parse my $("page") with the already initialized i18n instance.

Number formats

There is no possibility to account for different number formats or date formats

eg. british use 1,000.00 for one thousand
but germans use 1.000,00

or is something like this already implemented in i18next via sprintf?

Parse error using UglifyJS for file i18next-1.3.1.js

At my project we used to use i18next 1.2.3. It worked fine until I tried to run the site in IE9.
I found an issue about the IE9 compatibility which is solved in v1.2.4.

So I wanted to upgrade to the latest version.
If I use v1.3.1, I get an error in our build. We use UglifyJs (from requierJs) to package all our .js files and minify/uglify them.

I guess it's not working because i18next has had a major update (1.3.x). Using the latest version from the 1.2.x branch would easily solve it imho... But I can't find it. Can I download v1.2.5 somewhere?
Or can this issue be fixed in v1.3.1?

Linebreaks aren't displayed as expected

Using 'br' tags inside the json translation files doesn't result in a line break on a website.

Is there a way to add to add linebreaks in i18next ?
Or maybe a general way to encode html tags to render them as html ?

I didn't find any information on linebreaks in the documentation and currently I use spans seperated by 'br' tags or just 'p' tags in the html and use data-i18n names like: info1, info2 for each line which is kind of ugly.

Programatically set locale

How to perform a translation in server-side code, while forcing the locale to use? e.g.

var X = i18next.t( 'ns.common:app.name.') always returns english even though the nodejs session recognizes the i18next locale as e.g. de-DE

AMD support : problem with RequireJS

Hi,
I had a problem with RequireJS :

RequireJS configure paths :

require.config({
    paths: {
        'i18n': 'libs/i18next/i18next'
    }
});

Usage :

define(
    [
        'config',
        'i18n'
    ],

    function( config, i18n ) {

        return i18n.init(
            {
                lng: config.lang,
                getAsync: true
            }
        );

    }
);

Result in "i18n not defined".

I've modified my version of i18next (line ~46) :

...
if (typeof module !== 'undefined' && module.exports) {
    module.exports = i18n;
} else if (typeof define === 'function' && define.amd) {
    define(i18n)
} else {
...

and now it works

Fail silently when trying to access a path with children

//translation.json
"parent": {
  "child1": "foo",
  "child2": "bar"
}

//app.js
i18next.t('parent'); //Produces: TypeError: Object #<Object> has no method 'indexOf'

It should fail silently, as it does if you access a full non-existant path, e.g. i18next.t('parent.foo')

Compatibility with jQuery UI Dialog and Button

I think it can be useful to other people, so I am posting this here. Feel free to move, remove, comment, ...

There is no easy way to add the attribute "data-i18n" to the buttons when creating a dialog.
(I specifically need to add that attribute to allow for retranslation without reloading the page.)

When you do:

$("#dialog").dialog(
    buttons: [
        {
            text: "This is untranslated",
            "class": "button-ok",
            "data-i18n": "button_ok"
        }
    ]
);

You get the button:

<button type="button" id="button-ok" class="button-ok ..." data-i18n="button_ok" ...>
    <span class="ui-button-text">This is untranslated</span>
</button>

There is no easy way to add an attribute to the span.ui-button-text
The code that generates the buttons is in the function _createButtons line 9229 of jquery-ui 1.8.22

Solution 1: Set manually the attribute to the label, after the dialog creation

$(".button-ok .ui-button-text", $("#dialog").dialog("widget")).attr("data-i18n", "button_ok");

Solution 2: Automate the attribute move at button creation and destruction

// Checks the presence of the button component of jQuery UI:
if( $.fn.button ) {
    // Keep a reference to the original _create function:
    var _create_orig = $.ui.button.prototype._create;
    $.ui.button.prototype._create = function( ) {
        _create_orig.apply( this, arguments );
        if( this.type === "button" ) {  // Not needed for input, radio or checkbox
            var data_i18n = this.buttonElement.attr( "data-i18n" ),
                data_i18n_options = this.buttonElement.attr( "data-i18n-options" );
            // If found, apply the attributes to the button label:
            if( data_i18n || data_i18n_options ) {
                var button_text = this.buttonElement.find( ".ui-button-text" );
                this.buttonElement.removeAttr( "data-i18n" ).removeAttr( "data-i18n-options" );
                if( data_i18n ) button_text.attr( "data-i18n", data_i18n );
                if( data_i18n_options ) button_text.attr( "data-i18n-options", data_i18n_options );
            }
        }
    };
    // Keep a reference to the original destroy function:
    var destroy_orig = $.ui.button.prototype.destroy;
    $.ui.button.prototype.destroy = function( ) {
        if( this.type === "button" ) {
            var button_text = this.buttonElement.find( ".ui-button-text" ),
                data_i18n = button_text.attr( "data-i18n" ),
                data_i18n_options = button_text.attr( "data-i18n-options" );
            // If found, apply the attributes to the button element:
            if( data_i18n ) this.buttonElement.attr( "data-i18n", data_i18n );
            if( data_i18n_options ) this.buttonElement.attr( "data-i18n-options", data_i18n_options );
        }
        destroy_orig.apply( this, arguments );
    };
}

EDIT: The newest version of the above code can be found here: http://gist.github.com/3352659

You can find the jsFiddle where I have done my tests: http://jsfiddle.net/jlgrall/BzD3C/

What do you think ?
Has anyone another idea ?
What about the dialog title ?

crashes after upgrading from 1.2.5 to 1.3.1 (Cannot read property 'length' of undefined)

Hi

The current version of i18next makes some troubles on such request:

/locales/resources.json?lng=en-US+en+dev&ns=translation

with this crash:

TypeError: Cannot read property 'length' of undefined
    at Object.fetch (server/node_modules/i18next/lib/i18nextWrapper.js:191:37)
    at Object.load (server/node_modules/i18next/lib/i18nextWrapper.js:174:22)
    at server/node_modules/i18next/lib/i18next.js:128:23
    at callbacks (server/node_modules/express/lib/router/index.js:272:11)
    at param (server/node_modules/express/lib/router/index.js:246:11)
    at pass (server/node_modules/express/lib/router/index.js:253:5)
    at Router._dispatch (server/node_modules/express/lib/router/index.js:280:4)
    at Object.handle (server/node_modules/express/lib/router/index.js:45:10)
    at next (server/node_modules/express/node_modules/connect/lib/http.js:204:15)
    at server/node_modules/i18next/lib/i18next.js:67:13

fails to load json file resources

Hi,
I have setup the library in my html page but it fails to load the resource (as json).

The json file is correctly loaded (checked with firebug) with response:
{
"MobyleConfigs": 'Configuration'
}

The issue is, I think, that response is not handled as JSON but text.
This is rendered as a static asset by the framework (though ni header content-type looks fine: Content-Type:application/json; charset=UTF-8).

Here are the "logs" with debug:
currentLng set to: en-US i18next-1.5.10.min.js:5
failed loading: /static/locales/en-US/translation.json

Any idea ?

Thanks

Made possible to use i18next with rhino.

It will allow to use same i18n engine on a server-side and on a client-side. There are enough template engines which are runs using Rhino backend, but their lack or i18n support.
Right now i18next reference to jquery extend function and window object, for locale detection

"Post missing resources" feature is not working

It seems it never passes the actual data to post/get when sending missing resources. It only passes options.async while the data is in options.data

http[methode](options.url, {async: options.async}, function (status, data) {
    if (status === 200) {
        options.success(data.json(), status, null);
    } else {
        options.error(data.text(), status, null);
    }
});

Also the method always defaults to "GET" and it's not possible to change it in config as options.sendType is always undefined.

var methode = options.sendType ? options.sendType.toLowerCase() : 'get';

Default values are not "post processed"

I'm not sure whether this is intended or not but default values are not passed through applyReplacement() and applyReuse(). Therefore, it is not possible to use variable replacement or nested resources with default values.

Example to reproduce:

i18n.t('test', {defaultValue: 'Content of variable: __myVar__', myVar: 'foo'})

Encoding special characters (accent)

Hi, I'm a new user.
I have an issue with special characters, I can't display them correctly in my page.
Here is what i got in my json (fr-FR) file :

{
"app": {
"name": "i18n",
"welcome": "Bienvenus ร  tous"
}
}

When the text is displayed, the accent is not shown as it should be.
I tried to change the "ร " with "ร " but it doesn't solve the problem.
Anyone know what I can do ti make it work?

Workable versions

Please, add versions to the lib, to have an ability to install direct version.
Like 'bower install i18next#version...'
Thanks :)

Exception when context object has `null` properties and value replacement is requested.

Had an issue where my context contained a property that itself had a property that was null. Got an exception:

Uncaught TypeError: Cannot read property 'length' of null jquery.js:638
jQuery.extend.each jquery.js:638
applyReplacement i18next.amd.withJQuery-1.5.8.js:662
(anonymous function) i18next.amd.withJQuery-1.5.8.js:664
jQuery.extend.each jquery.js:660
applyReplacement i18next.amd.withJQuery-1.5.8.js:662
(anonymous function) i18next.amd.withJQuery-1.5.8.js:664
jQuery.extend.each jquery.js:660
applyReplacement i18next.amd.withJQuery-1.5.8.js:662
_translate i18next.amd.withJQuery-1.5.8.js:779
translate i18next.amd.withJQuery-1.5.8.js:699

Did some research and found:

   function applyReplacement(str, replacementHash, nestedKey) {
        if (str.indexOf(o.interpolationPrefix) < 0) return str;

        f.each(replacementHash, function(key, value) {
            if (typeof value === 'object') {
                str = applyReplacement(str, value, nestedKey ? nestedKey + '.' + key : key);
            } else {
                str = str.replace(new RegExp([o.interpolationPrefix, nestedKey ? nestedKey + '.' + key : key, o.interpolationSuffix].join(''), 'g'), value);
            }
        });
        return str;
    }

Should be:

   function applyReplacement(str, replacementHash, nestedKey) {
        if (str.indexOf(o.interpolationPrefix) < 0) return str;

        f.each(replacementHash, function(key, value) {
            if (typeof value === 'object' && value !== null) {
                str = applyReplacement(str, value, nestedKey ? nestedKey + '.' + key : key);
            } else {
                str = str.replace(new RegExp([o.interpolationPrefix, nestedKey ? nestedKey + '.' + key : key, o.interpolationSuffix].join(''), 'g'), value);
            }
        });
        return str;
    }

Because typeof null === 'object'

I made this change and it got better.

Add namespace to fallback or current language at run time

I am using "RequireJS" for on demand file and module loading. My language bundle is residing within the module itself.

So, my language bundle loads along with module. And because of this i need to add particular namespace to any of the language which is previously loaded by any other module.

for eg.
My first module has following language JSON,

var resources = {
    "dev" : {
        "translation" : {
            "title" : "Mr."
        }
    },
    "en" : {
        "translation" : {
            "last" : "Chauhan"
        },
        "name" : {
            "second" : "Jashvantsinh"
        }
    },
    "en-US" : {
        "name" : {
            "first" : "Virbhadrasinh"
        }
    }
};

And inside my first module i will do

      i18n.init({
           resStore : resources,
           lng: "en-US",
           debug : true,
           seLocalStorage: true,
           localStorageExpirationTime: 86400000
       });

Now, my second module has following language JSON,

var resources = {
    "dev" : {
        "translation" : {
            "e-mail" : "e-mail"
        }
    },
    "en" : {
        "translation" : {
            "pinCode" : "Pin Code : "
        },
        "Address" : {
            "phone" : "Your Phone : "
        }
    },
    "en-US" : {
        "address" : {
            "city" : "City Name : "
        }
    }
};

So, I have to merge all these into "i18n.options.resStore" within specified language at run time.

Is there any way to do this in current version of "i18next"?

Allow empty strings for translations

Currently if I was to define the following:

{
  key: ''
}

and called it:

i18n.t('key')

I would be returned 'key'

I find it useful to allow empty strings as proper values in the case where I recieve a list of status messages from the backend that are more verbose than what I want on the client.

For instance if the server provides three states for a notification: ['new','seen','done'], i may want the translation to look like this:

{
  notifications: {
    new: 'New'
    seen: ''
    done: ''
  }
}

so a call to i18n.t('notifications.seen') would return ""

IE9 http://i18next.com/pages/test.html fail

with passed in resource set
โœ–
"before each" hook
ReferenceError: 'console' is undefined

Yes I understand IE is evil, etc., if you can get all the users off it that would be fine, but until then...

Using i18next with moment.js

Does anyone know a way to sync the language selection between i18next and moment.js? I mean something like:

app.locals({
  format_date: function(val) {
    moment.lang(i18next.lng());
    return moment(val);
  }
});

Thanks

default type for GET-request

We use i18next in a project with the default ajax type set to POST and I need to set the ajax-requests in _fetch and _fetchOne everytime I update i18next.
I would suggest to set the type to GET as default.

How embed json

Is it possible to set translation json hard into javascript code, to avoid ajax calls or localstorage ?
I can not find an example.
Cordially
Ami44

complex key does not get recognised

{
"nl": {
"translation": {
"Going to the next page. Be aware it will not save changes, so make sure you've saved first or use 'Save & Next'": "this does not get translated",
"hello world": "Hallo wereld!"
}
}
}

i18n.locale = 'nl'
i18n.t("Going to the next page. Be aware it will not save changes, so make sure you've saved first or use 'Save & Next'") //outputs the key instead of 'this does not get translated'
i18n.t("hello world") // outputs 'Hallo wereld!'

using i18next-1.5.7.js

greetings,

Mischa

Return a promise at init

It could be great if i18next return a promise a init instead (or in parallel) of using a callback.

So I can use i18next async as the jquery async way.

Thanks!

Cookie locks the user choice to change his preferred language

I wonder why you need to set the cookie by default.
I mean, if you are able to get the language of the navigator once, there is no reason you wouldn't be able to get it again the next time. So why do you store it in a cookie ?

Here is a little reflection about it.

It does make sense to set the cookie, if the language is forced, for example by a querystring parameter or through a language selector in the webpage.

But if you force the cookie by default then it prevents the user to choose another language through the navigator language preferences, or the OS language. Cases where it can be annoying:

  • developers or translators working on a page who need to change the language often.
  • computer used by multiple users who use different languages.

What do you think ?

PS: I know you recently added the option to disable the cookie. I will use that. But nonetheless, it would be better to automatically create the cookie when the language is forced.

Don't use alerts as content areas on your website

Hi,

This seriously impairs usability. Just let them be normal lists (and stuff) and it'll be easier to read.

Even the node.js download instruction is an alert and is then understood as such by your users!

Make it more clear that jQuery is (semi-)required

The documentation does state that jQuery is required for i18next to work. Currently it is required to have either jQuery or implement the missing functions (extend, each, ajax) yourself. I would suggest making it more clear on the documentation pages

interpolationPrefix and interpolationSuffix may have a RegEx meaning

i18next ignores the case where interpolationPrefix and interpolationSuffix options have a meaning in a regular expression, in the applyReplacement() function. If I set them to { and } respectively, the RegEx object thinks the string to find is a quantifier, and throws an error.

the interpolationPrefix and interpolationSuffix should be prefixed with a backslash to avoid this.

this is a patch from my svn:

Index: i18next-1.5.8.js
===================================================================
--- i18next-1.5.8.js    (revision 6274)
+++ i18next-1.5.8.js    (revision 6275)
@@ -665,8 +665,8 @@
         f.each(replacementHash, function(key, value) {
             if (typeof value === 'object') {
                 str = applyReplacement(str, value, nestedKey ? nestedKey + '.' + key : key);
-            } else {
-                str = str.replace(new RegExp([o.interpolationPrefix, nestedKey ? nestedKey + '.' + key : key, o.interpolationSuffix].join(''), 'g'), value);
+            } else {
+                str = str.replace(new RegExp(['\\' + o.interpolationPrefix, nestedKey ? nestedKey + '.' + key : key, '\\' + o.interpolationSuffix].join(''), 'g'), value);
             }
         });
         return str;

Cannot hardcode something else than text inside a tag

With the following json:

{
  "app": {
    "name": "i18next"
  },
  "nav": {
    "brand": "Company name",
    "language": "Language",
    "english": "English",
    "french": "French",
    "spanish": "Spanish",
    "german": "German"
  }
}

How do you get the following:

<a href="#" class="dropdown-toggle" data-toggle="dropdown" data-i18n="nav.language">Language <b class="caret"></b></a>

(How do I add <b class="caret"></b> to the a text, or can I harcode it?)

I cannot think of an easy way.

Trouble loading and initializing i18next with Backbone and Require.js

I'm developing a one page application using backbone, for the i18n i would like to use i18next but I'm experiencing big trouble to load and initialize i18next properly using requirejs. I'm using the jQuery plugin and the data attributes in html tags to perform the translations, so i would like to initialize i18next once, in the application bootstrap and perform the translations on the document ready event.

My requirejs initialization looks as follows:

    require.config({
    baseUrl : './',
    paths : 
    {
        /** Vendor **/
        jquery : 'js/vendor/jquery/jquery.min',
        underscore : 'js/vendor/underscore/underscore-optamd-min',
        backbone : 'js/vendor/backbone/backbone-optamd-min',
        bootstrap : 'js/vendor/bootstrap/amd/bootstrap',
        text : 'js/vendor/require/text',
        order : 'js/vendor/require/order',
        json : 'js/vendor/json/json2',
                i18n : 'js/vendor/i18next/i18next.min',

        /** General Folder Routes **/
        vendor: 'js/vendor',
        libs : 'js/libs',
        utils : 'js/utils',     

        /** App Folder Routes **/
        templates : 'templates/private',
        app : 'app/private',
        modules : 'app/private/modules',

        /** Else... **/     
        vm : 'js/utils/vm',
        buffer : 'js/utils/buffer', 
        basemodel : 'js/utils/baseModel',
        basecollection : 'js/utils/baseCollection',
        highcharts : 'js/vendor/highcharts/js/highcharts',
        fullcalendar : 'js/libs/fullcalendar/fullcalendar.min',
        chosen : 'js/libs/chosen/chosen.jquery.min'
    },
    shim: {
        'i18n': {
            deps: ['jquery'],
            exports: 'i18n'
        }
    },
    packages : [
                "layout", 
                {
                    name : "layoutView",
                    main : "../app/private/modules/layout/layoutView"
                } 
               ],
    urlArgs : "v=" + '2' + '&bust=' + (new Date()).getTime() 
});

require([ 'jquery', 'underscore', 'backbone', 'json', 'i18n', 'utils/plugins', 'vm', 'app/app', 'app/router', 'buffer'], function($, _, Backbone, JsonJS, i18n, Plugins, Vm, App, Router, Buffer) {

    Router.initialize();

});

and my app main app is as follows:

    define([ 'jquery',
         'underscore',
         'backbone',
         'vm',
         'i18n',
         'layoutView'
], function($, _, Backbone, Vm, i18n, LayoutView) {

    var App = Backbone.View.extend({

        el: 'body',

        initialize: function () 
        {

            i18n.init({ lng: "es", fallbackLng: "en", useDataAttrOptions: true, debug: true }).done(function(){

                var layoutView = Vm.create('layoutView', LayoutView);main app f

                $(document).ready(function(){
                    $('.i18n').i18n();
                });

            });

        }

    });

    return new App;
});

using this configuration i18next sometimes loads fine and works flawlessly and sometimes it tries to load itself before jQuery, so the deferred object in lines 529 - 534 in the init method of i18next is undefined:

            // jQuery deferred
        var deferred;

        if ($ && $.Deferred) {
            deferred = $.Deferred();
        }

I've tried to initialize i18next before and after Router.initialize(), doesn't work. Tried to load the translation files syncronous and asyncronous, nothing works: I like i18next and I would like to use it in my project, but this issue is driving me mad.

Any clue or pointing finger in the right direction is really appreciated.

Thanks in advance.
Diego.

Formatted text or at least line breaks

It would be great to be able to use html formatted text in translations or at least use line breaks (html ones or just \n), so you can translate a little longer texts with paragraphs and probably highlight some of the text.

how to load additional namespaces when using a set namespace path?

I'm trying to load namespaces on demand using:

i18n.loadNamespace(["age"], function() { /* loaded */ });

However, when initializing i18next like this:

// i18next options
locales = { 
    lng: 'de-DE',
    load: 'current',
    fallbackLng: false,
    resGetPath: '../lang/__lng__/__ns__.json',
    ns: 'gen'
    }
i18n.init(locales);

The regGetPath will be broken when loading additional namespaces.

Firebug tells:

http://www.page.de/test2012/lang/de-DE/__ns__.json

So the speficied namespace age does not make it into the ajax request.

Is there anything I'm doing wrong or could this be a bug?

useLocalStorage is set to true I don't get any translation

Hello, if I have the following:

  $.i18n.init({
      dynamicLoad: true
    , fallbackLng : 'en-US'
    , resGetPath : 'locales/resources.json?lng=__lng__&ns=__ns__'
    , useLocalStorage: true // in production you could use this
  }, function(t) {
     console.log(t('creator.firstname'));
  });

I don't get any translation... but if I set useLocalStorage : false then it works fine, I'm a bit confused with that...

Thanks :)

data-i18n doesn't seem to work

Hi,

First of all great plugin!

I just tested "data-i18n" role and it doesn't seem to work. I just tested this simple code with the appropriate json files:


<script type="text/javascript" src="jquery-1.7.1.min.js"></script> <script type="text/javascript" src="i18next-1.2.3.js"></script> <script> $.i18n.init({ lng: 'fr-FR', fallbackLng: 'en-US', ns: 'translation', useLocalStorage: false }, function() { $('#test').i18n(); }); </script> ##

Obviously, when i replace
$('#test').i18n();
by
$('#test').text($.t('test.name'));
it works.
Maybe I'm missing something?

maybe it will help: when i put an alert near line 180 in i18next-1.2.3.js the alert doesn't show.

regards.

var replacement not working with "returnObjectTrees" option

always replace with value from FIRST call.

app.get('/debug', function(req, res) {

    var ret = "";
    var eol = "<br>"; var eol2 = eol + eol;
    var replace_A = {user:"user A", lng:'EN', returnObjectTrees:true};
    var replace_B = {user:"user B", lng:'ES', returnObjectTrees:true};
    var replace_C = {returnObjectTrees:true};
    var node = "email.content";
    //"content": {"t02": "Hi __user__!", .... },

    ret += "DEMO i18next returnObjectTrees always use 1st replaceValue" + eol;
    ret += "node : " + node + eol2;

    ret += "replace_A : " + JSON.stringify(replace_A) + eol;
    ret += "A : " + JSON.stringify(i18next.t(node,replace_A)) + eol2; // "hi user A"

    ret += "replace_B : " + JSON.stringify(replace_B) + eol;
    ret += "B : " + JSON.stringify(i18next.t(node,replace_B)) + eol2; // "hi user A"

    ret += "replace_C : " + JSON.stringify(replace_C) + eol2; 
    ret += "C: " + JSON.stringify(i18next.t(node,replace_C)) + eol2; // "hi user A"

    res.send(ret);
});

Allow "translate" method to return map when use of partial nesting

For example :

// given resource
"app": {
  "area": "Area 51",
  "district": "District 9 is more fun than $t(app.area)"
}

$.t('app'); 

Will return

 {
  "area": "Area 51",
  "district": "District 9 is more fun than $t(app.area)"
}

Is will be quite usefull then UI component uses maps to handle i18n

Setup the default language of your site

An easy way to write a web is write it in a default language for example en-US.

<HTML>
   <HEAD>...</HEAD>
   <BODY>
         ........
         <DIV class="i18nGroup">
         ........
               <P data-i18n="i18nGroup.myText"> my english content </P>
        .........
        </DIV>
        ........
        <script>
            $.i18n.init(
                {
                      resGetPath: './locales/__lng__/ns.common.json'
                    , useLocalStorage: false
                    , debug: true
***********************************************************************
                    , pageDefaultLanguage: 'en-US'
***********************************************************************
                }
                , function() {
                    $('.i18nGroup').i18n();
                }
            );
        </script>
   </BODY>   
</HTML>

If you has this page for example... I should be able to setup i18next that my page is in 'en-US' and it hasn't to translate nothing when the locale is setup to 'en-US'... simply it has to show the page. If the browser, the url param... set the locale to another language then it will have to translate the page...

Setup the default language of your site

An easy way to write a web is write it in a default language for example en-US.

<HTML>
   <HEAD>...</HEAD>
   <BODY>
         ........
         <DIV class="i18nGroup">
         ........
               <P data-i18n="i18nGroup.myText"> my english content </P>
        .........
        </DIV>
        ........
        <script>
            $.i18n.init(
                {
                      resGetPath: './locales/__lng__/ns.common.json'
                    , useLocalStorage: false
                    , debug: true
***********************************************************************
                    , pageDefaultLanguage: 'en-US'
***********************************************************************
                }
                , function() {
                    $('.i18nGroup').i18n();
                }
            );
        </script>
   </BODY>   
</HTML>

If you has this page for example... I should be able to setup i18next that my page is in 'en-US' and it hasn't to translate nothing when the locale is setup to 'en-US'... simply it has to show the page. If the browser, the url param... set the locale to another language then it will have to translate the page...

postMissing: url is not defined

I found an error in the postMissing ajax functions on line 663.
Uncaught ReferenceError: url is not defined

f.log('posted missing key \'' + key + '\' to: ' + url); // line 663 success-function
// [...]
f.log('failed posting missing key \'' + key + '\' to: ' + url); // line 637 error-function

I think the url should be item.url.

Typos in website

A few typos in your i18next website.

Page: Documentation -> Features

Section "simple plural":
i18n.t("key", { count: 0 }); // -> 0 children -> i18n.t("key", { count: 0 }); // -> 0 child

Section "use translation contexts":
friendt_male -> friend_male

Issue with plural conditions

Might not be a bug in the code. Might be a lack of documentation.

My translation.json:

{
    "notifications": {
        "haveunread":           "You have __count__ unread notification",
        "haveunread_plural_1":  "You have __count__ unread notifications",
        "haveunread_plural_20": "You have __unread__ unread notifications"
    }
}

My test cases:

var unread = count = 1;
$.t("notifications.haveunread", {count: count, unread: unread})
// ==> You have 1 unread notification (correct!)

unread = count = 10;
$.t("notifications.haveunread", {count: count, unread: unread})
// ==> You have 10 unread notifications (correct!)

unread = "20+";
count = 20;
$.t("notifications.haveunread", {count: count, unread: unread})
// ==> You have 20 unread notification (incorrect)

unread = "20+";
count = 50;
$.t("notifications.haveunread", {count: count, unread: unread})
// ==> You have 50 unread notification (incorrect)

Basically, my desired effect is to have counts of 20 or more show up as "20+".

Do you plan gettext (po/mo) compatibility ?

Hi,

First of all, good job with this lib!

Do you plan to add support for i18n translation files and domains (gettext, po/mo parser) ?
I've found a lib that implement gettext in js but not as clear and usefull as your lib : http://jsgettext.berlios.de/.

It would be extremely useful for webapps made with Django or Ruby on Rails to share translation files between server and client environments.

Bye,


n.vandamme

Make possible to translate multiple attributes per tag

Hi there,

Would be fantastic is you add the possibility to translate multiple attributes pero HTML tag, for example, if I've got an input tag I would like to translate the placeholder attribute and the title attribute used in a tooltip library to show informtaion on how to fill the field.

I'm talking about using the jquery selectors and plugin.

Thanks in advance.

Regards, Diego.

translate function replacement - feature request

Would be nice to allow the use of interpolationPrefix and interpolationSufix options at translate function as you may use i18next at level (ex: view) where you receive messages from different libraries with different formats.

Need some fallback for Namespace.

I have following JSON for language, Handlebars helper and HTML

  1. JSON for language

    var resources = {
    "dev" : {
        "translation" : {
            "title" : "Mr."
        }
    },
    "en" : {
        "translation" : {
            "last" : "Chauhan"
        },
        "name" : {
            "second" : "Jashvantsinh"
        }
    },
    "en-US" : {
        "name" : {
            "first" : "Virbhadrasinh"
        }
    }
    };
    
  2. Handlebars helper

    Handlebars.registerHelper('t', function(key, nameSpace ) {
      return $.i18n.t(key,nameSpace);
    });
    
  3. HTML
    var nameSpace = {
    ns : 'name'
    };

    <div>
    <span>{{t "title" nameSpace}}</span>
    <span>{{t "first" nameSpace}}</span>
    <span>{{t "second" nameSpace}}</span>
    <span>{{t "last" nameSpace}}</span>
    </div>

Now, whenever i am trying to render this HTML, it will not give me values for keys "title" and "last" because they are not in "name" nameSpace.

So, i need some fallback which look into default nameSpace if key is not found in given nameSpace.

So, I added "found = translate(key);" inside last if condition of "_translate" function and its working fine but its recursive function call. So, it may affect the performance.

Code :

     if (found === undefined) {
            notfound = applyReplacement(notfound, options);
            notfound = applyReuse(notfound, options);
            //Added line for namespace fallback...
            found = translate(key);
     }

Is that necessary to load all locale file?

Hi,
I try to use i18next in our projects to handle i18 and it's really helpful. However, we find out that if you use static files combine with getAsync: false, it might cause one situation.

If I use this option to init i18next, and current language is en-US

resGetPath: "/locale/lng.json"

It will load en-US.json, en.json, dev.json by sequence. But is that really necessary to load all the files, cause if I only have one file exists (ie, en.json), why not just load it (at least one locale file) then keep doing other things. If we want to fetch locale files sync and it miss some files, it'll block the program.

Or maybe we just use the wrong way? Any suggestion? Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.