Giter Site home page Giter Site logo

require-i18next's Introduction

THIS PROJECT IS NO LONGER MAINTAINED

require-i18next

A RequireJS plugin for requiring and optimizing translations using i18next.

NOTE: This plugin does not support i18next version 2.x

The plugin supports both RequireJS and Almond.

Usage

Loading locales

The require-i18next plugin makes is able to load locales as dependency in requirejs by simply using the prefix i18n! followed by a path to the directory of your locales.

require(["some/module", "i18n!path/to/locales"], function(module, i18n) {
    // The i18n variable is an instance of i18next
    // So right here you can for example call i18n.t("some_key")
    // to get the translation for "some_key"
    // (See the i18next docs for more details)
});

Loading additional namespaces

With i18next you can load multiple namespaces and refer to them when calling translate with a key (for example i18next.t("namespace:key")).

This plugin gives you the option to load additional namespaces immediately when loading a locale by doing:

require(["some/module", "i18n!path/to/locales:namespace1,namespace2"], function(module, i18n) {
    // The additional namespaces "namespace1" and "namespace2" are now loaded
    // So right now we can for example call i18n.t("namespace1:some_key")
    // to get the translation for "some_key" in namespace "namespace1"
    // (See the i18next docs for more details)
});

Special notes

When loading multiple locale files from different locations within the same requirejs module, the locales will be merged. So for example if you load the following locale files in the same module:

// Locale file 1
{
    "key1": "value1",
    "key2": "value2"
}

// Locale file 2
{
    "key1": "value1",
    "key2": "value2"
}

// Later in the code
i18n.t("key1");

The second translations will overwrite the first translations (because the keys are the same). To prevent these overriding, it is always a good idea to put the keys in a separate (unique) scope, so for example:

// Locale file 1
{
    "translations1": {
        "key1": "value1",
        "key2": "value2"
    }
}

// Locale file 2
{
    "translations2": {
        "key1": "value1",
        "key2": "value2"
    }
}

// Later in the code
i18n.t("translations1.key1");

This way, loading both locales will not override any existing translations within the same namespace.

Setup and Configuration

Setup plugin

Below follows a basic example on how to set up the plugin in requirejs.

requirejs.config({
    map: {
        "*": {
            i18n: "path/to/require/i18next/plugin"
        }
    },
    paths: {
        i18next: "path/to/i18next"
    }
});

Now you can use the i18n! prefix to load locales.

Basic configuration

Normally i18next is initialized with options by calling i18next.init().This plugin makes it able to define the i18next options in the requirejs configuration:

requirejs.config({
    i18next: {
        ns           : "messages",
        fallbackLng  : "en",
        detectLngQS  : "locale",
        lowerCaseLng : true,
        useCookie    : false,
        resGetPath   : "__ns__.__lng__.json"
    }
});

The plugin will pass the options to i18next when loading locales.

Advanced configuration

Currently i18next will try to load the locales it has detected from a user's browser or cookie, first by trying the specific locale, secondly by trying the unspecific locale and finally by trying the fallback locale. So for example when it has detected nl-NL, it will try to load nl-NL -> nl -> en (when en is set as fallback language). So it tries to load each locale, even if you don't have support for one of them.

The plugin adds an extra option "supportedLngs" to define the languages and namespaces you do support and will only try to load a locale if it is supported.

The supported languages can be defined by languages and namespaces pairs:

requirejs.config({
    i18next: {
        supportedLngs: {
            en: ["namespace1", "namespace2"],
            nl: ["namespace1"]
        }
    }
});

It is also possible to define the supported languages with a scope:

requirejs.config({
    i18next: {
        supportedLngs: {
            "path/to/locales1": {
                en: ["namespace1", "namespace2"],
                nl: ["namespace1"]
            },
            "path/to/locales2": {
                en: ["namespace1"]
            }
        }
    }
});

With the above example when loading locales with "i18n!path/to/locales1"only the languages defined in the "path/to/locales1" scope will be used as supported languages.

Optimization

Inlining locales

The plugin supports inlining of locales when optimizing with requirejs. When inlining, the plugin will load all the locale files used in each module and add them to the final build file. After the build process, i18next doesn't have to dynamicly load any locales anymore.

Note: the supportedLngs option is needed for inlining locales (see Advanced configuration)

Single module build configuration

({
    // Enable inlining locales
    inlineI18next: true, 
    
    // Plugin code is not needed anymore when inlining locales
    stubModules: ["path/to/require/i18next/plugin"],
    
    // Add the i18next lib as dependency to the module
    // (it is not included by the plugin when building)
    shim: {
        "main": ["i18next"]
    },
    
    // The name of the module to build
    name: "main",
    
    ...
})

Multiple module build configuration

({
    // Enable inlining locales
    inlineI18next: true, 
    
    // Plugin code is not needed anymore when inlining locales
    stubModules: ["path/to/require/i18next/plugin"],
    
    // Add the i18next lib as dependency to the modules which use the plugin
    // (it is not included by the plugin when building)
    shim: {
        "first": ["i18next"],
        "second": ["i18next"]
    },
    
    // The modules to build
    modules: [
        {
            name: "first"
        }, 
        {
            name: "second"
        }
    ],
    
    ...
})

Download

Latest release

Changelog

Changelog

License

This project is released under the MIT license.

require-i18next's People

Contributors

jcbvm avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar

require-i18next's Issues

Loading additional namespaces several times doesn't work

Here's a simple use case: I have one main namespace, called main, and two additional namespaces, called add1 and add2. Then I have two buttons, button1 and button2, that when clicked load their corresponding namespace and display some text using it.

    $('#button1').click(function () {
        require(['i18n!../locales:add1'], function (i18n) {
            $('body').append(i18n.t('add1:test1'));
        });
    });

    $('#button2').click(function () {
        require(['i18n!../locales:add2'], function (i18n) {
            $('body').append(i18n.t('add2:test2'));
        });
    });

If I click on button1, then button2, then button1 again, an untranslated text will be displayed. This wouldn't be the case if I used

i18n.loadNamespace('add1', function () {

instead of

        require(['i18n!../locales:add1'], function (i18n) {

Cannot build

Thanks for the plugin and it works but once I start trying to compile/build all the files, I get this error:

[Error: TypeError: Cannot read property 'functions' of undefined

+ a tree of packages all the way to "i18n"

Do I have to do a shim config or something?

Optimizer won't work

When I optimize my project, and I use "i18n!locales" dependencies, require JS tries to load /root/url/i18n.js what will return a 404 error in my app/browser.

I've added inlineI18next: true in my build.js and my config.js looks like this:

    map: {
      "*": {
          i18n: "vendors/require-i18next/i18next"
      }
    },

    paths: {
        .........
        "i18next": "vendors/i18next/i18next.amd.withJQuery.min",
        "locales": "i18n/locales",

Without optimizing, everything works fine. It seems that it will never run the code in the i18next-builder file.

almond

Hi, the plugin doesn't play well with an optimized build incorporating almond. I don't know all of the reasons yet, but it appears at least to be related to the requirement that requirejs call the Load function.

Switching from requirejs/i18n to require-i18next

Hi guys,

it seems require-i18next is the plugin I've searched for. Because with the default i18n plugin offered by require.js I've got a lot of problems when running the r.js optimizer.

I've seen that with the i18next plugin, you always have to call a method to get the values into your module/template etc. Due to the fact, that our project has grown and is very big there is a lot of rework to do. Is there a possibility to require the translations-files in the way, we already do it?

For example instead of:

   require(["some/module", "i18n!path/to/locales"], function(module, i18n) {
    console.log(i18n.t("some_key"));

use this kind of access to the translation files

require(["some/module", "i18n!path/to/locales"], function(module, locales) {
    console.log(locales.some_key);

In addition I'm also wondering, hove to pass the locals to our underscore templates. For example at the moment we do the following. define a backbone view, and pass the labels to the template

define([
    // labels
    'requirejs-i18n!nls/labels',
    // View Templates
    'text!templates/users/register/layout.html'
], function(
    Labels,
    // View Templates
    Template
) {
    'use strict';
    return Sportly.LayoutView.extend({
        template: function() {
            return _.template(Template, {
                labels: Labels
            }, {
                variable: 'data'
            });
        }
    });
});

and use them in the template like this

<h4 class="text-margin text-white text-big"><i class="fa fa-lock"></i>
    <%= data.labels.regions.modals.register.heading %>
</h4>

thanks in advance. If there is a possible to achieve this, it would be awesome.

Empty name argument with inline builder and namespace config format.

When building the inline language strings, the name variable in https://github.com/jcbvm/require-i18next/blob/master/require-i18next/i18next-builder.js#L99 seems to be empty, and its attempted to be used to derive more information at https://github.com/jcbvm/require-i18next/blob/master/require-i18next/i18next-builder.js#L115-L117

I imagine it is not supposed to only be an empty string, but I'll admit I don't know what it should contain normally. This causes problems in https://github.com/jcbvm/require-i18next/blob/master/require-i18next/i18next-builder.js#L135 because it gets an / appended to it, thus becomes simply / and then resolving fails.

Another problem I'm having is that require-18next expects the ns option to be a string, while according to the i18next documentation ("Multiple namespace" at http://i18next.com/pages/doc_init.html) it can also be an object with the namespaces and defaultNS properties.

I made a branch (https://github.com/mathieumg/require-i18next/tree/config_inline_namespaces) where I handle both shapes of the ns property. I commented out line 135 just as a workaround for the time being (everything still works and all tests pass), but I'm curious as to what the right fix is, regarding that.

I can submit that as a PR here if you want to and I'll do it once I know what to do with the module/name problem!

Thank you

Default namespace file loaded several times

Let's assume I have a two translation files, main.json and module.json in my locales directory. My configuration is:

 i18next: {
        ns: 'main',
        resGetPath: "__lng__/__ns__.json"
    }

I initialize my app with:

require(['jquery', "i18n!../locales"], function (){
// here I can use tranlations from main.json
});

Later on, I load my module with:

require(['jquery', "i18n!../locales:module"], function (){
// here I can use tranlations from module.json
});

The problem is that when loading my module, request for both main.json and module.json are sent. Would it be possible to only load module.json ?

Can't get optimizer to work

Hi There,

I have the require-i18next plugin working without the optimizer, but when I try to optimize it tries to load a library called i18n at the root of my project and I receive the following errors.

GET http://localhost:8000/i18n.js req.load @ scripts.js?rev=1439951740950:11x.load @ scripts.js?rev=1439951740950:11y.load @ scripts.js?rev=1439951740950:11y.fetch @ scripts.js?rev=1439951740950:11y.check @ scripts.js?rev=1439951740950:11y.enable @ scripts.js?rev=1439951740950:11x.enable @ scripts.js?rev=1439951740950:11y.callPlugin @ scripts.js?rev=1439951740950:11y.fetch @ scripts.js?rev=1439951740950:11y.check @ scripts.js?rev=1439951740950:11y.enable @ scripts.js?rev=1439951740950:11x.enable @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11each @ scripts.js?rev=1439951740950:11y.enable @ scripts.js?rev=1439951740950:11x.enable @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11each @ scripts.js?rev=1439951740950:11y.enable @ scripts.js?rev=1439951740950:11x.enable @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11each @ scripts.js?rev=1439951740950:11y.enable @ scripts.js?rev=1439951740950:11x.enable @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11each @ scripts.js?rev=1439951740950:11y.enable @ scripts.js?rev=1439951740950:11x.enable @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11each @ scripts.js?rev=1439951740950:11y.enable @ scripts.js?rev=1439951740950:11y.init @ scripts.js?rev=1439951740950:11(anonymous function) @ scripts.js?rev=1439951740950:11
scripts.js?rev=1439951740950:11 Uncaught Error: Script error for: i18n
http://requirejs.org/docs/errors.html#scripterrormakeError @ scripts.js?rev=1439951740950:11x.onScriptError @ scripts.js?rev=1439951740950:11

I don't want to inline my resources to I haven't made any changes to my build settings for the optimizer. Do I need to make changes?

Failing to load i18next resources when running through Jasmine

I'm using grunt-contrib-jasmine to run some unit test through Grunt. Part of the unit tests is to load the i18next libs. However -- when running via Phantom JS -- the customLoad in require-i18next is failing.

I've tracked it down to line 130 in i18next.js in your lib.

To fix the problem, I made this change:

// Before
f.ajax({
    url: url,
    ...
})

// After
f.ajax({
    url: url.substring(1),
    ...
})

This removes the initial "/" that is added to the URL. With the slash - resources seem to fail with a "status:0" error.

Not sure if my fix is the right thing to do, but it was the only thing that worked for me. I think it has something to do with the fact that Phantom JS doesn't like loading from a different root path than it's running in. But this change doesn't seem to break anything else. Everything still loads fine in the browser and r.js can still optimize everything correctly.

Support for 'customLoad' param

Is it possible to use require-i18next while using a 'customLoad' function? Right now it doesn't seem to work. It's simply ignored.

If not -- is it possible to somehow specify more than one 'resGetPath' value? I have locales stored in various locations and need to dynamically set them.

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.