Skip to content

KevinNovak/Linguini

Repository files navigation

Linguini

NPM Version Downloads Stars License Pull Requests

Npm package - A JSON-based translation file manager.

npm install linguini

Table of Contents

Example

An example language file, lang.en.json:

{
    "data": {
        // This is a language category:
        "intro": {
            // This is a language item:
            "myFavoriteColor": "My favorite color is blue."
        }
    },
    "refs": {}
}

We could have additional translations of this file, for example: lang.fr.json, lang.ru.json, etc:

Using Linguini, we can retrieve the language item from the appropriate file by passing in the location of the item, and the language code to use:

let englishLine = linguini.get('intro.myFavoriteColor', 'en', TypeMappers.String);
console.log(englishLine);
// Outputs: "My favorite color is blue."

let frenchLine = linguini.get('intro.myFavoriteColor', 'fr', TypeMappers.String);
console.log(frenchLine);
// Outputs: "Ma couleur préférée est le bleu."

Here 'intro.myFavoriteColor' is the category and name of the language item, while 'en' or 'fr' tells Linguini which language file to pull from: either lang.en.json or lang.fr.json.

Side note: If you're wondering what the TypeMappers.String is for, see the section below on Type Mappers.

Initial Setup

Installation

npm install linguini

Creating a Linguini Object

import { Linguini } from 'linguini';

// The folder path containing the language files.
let folderPath = path.join(__dirname, './data');

// The base name of the language files to use. Note this should not include any file extensions or language codes.
let fileName = 'lang';

let linguini = new Linguini(folderPath, fileName);

Type Mappers

Type Mappers are a special kind of function which allow Linguini to convert the JSON language item that was retrieved from the language file into any type of your choice.

Built-In Type Mappers

Linguini has many built-in Type Mappers which can be used inside the Linguini#get() method to retrieve language item values as specific types.

Linguini's built-in Type Mappers:

  • String
  • Boolean
  • Number
  • BigInt
  • Date
  • RegExp
  • URL

For example, let's say you want Linguini to retrieve, not just a plain string, but a RegExp object. Linguini has a built-in Type Mapper to convert a JSON language item into a RegExp.

Simply import and use TypeMappers.RegExp inside the Linguini#get() method:

import { TypeMappers } from 'linguini';

// ...

let regex = linguini.get('regexes.hello', 'en', TypeMappers.RegExp);

And in our language file:

{
    "data": {
        "regexes": {
            "hello": { "pattern": "hello", "flags": "i" }
        }
    },
    "refs": {}
}

Notice how this language item is not just a string, but has 2 properties: pattern and flags. Using Type Mappers allows Linguini to convert just about any JSON data into any type you wish.

Custom Type Mappers

If Linguini doesn't have a built-in Type Mapper that suits your needs, you can always create you own. A Type Mapper is simply a function that takes the JSON language item and returns the mapped type.

For example, we can create Person Type Mapper, personTm:

let personTm = jsonValue => new Person(jsonValue.firstName, jsonValue.lastName);

And in our language file, we can define Person objects like so:

{
    "data": {
        "superheroes": {
            "batman": { "firstName": "Bruce", "lastName": "Wayne" },
            "superman": { "firstName": "Clark", "lastName": "Kent" }
        }
    },
    "refs": {}
}

Variables

Variables allow you to dynamically pass in values to your language items. A variable can be defined in a language file using double curly braces like so: {{MY_VARIABLE}}.

Here is a full example:

{
    "data": {
        "intro": {
            "welcome": "Welcome {{FIRST_NAME}} {{LAST_NAME}} to our club!"
        }
    },
    "refs": {}
}

Then in our code, we can pass in values for the variables like so:

let welcomeLine = linguini.get('intro.welcome', 'en', TypeMappers.String, {
    FIRST_NAME: 'Harley',
    LAST_NAME: 'Quinn',
});
console.log(welcomeLine);
// Outputs: "Welcome Harley Quinn to our club!"

References

If you find yourself repeating the same word or phrase over and over in a language file, then references will be your best friend! You can define a commonly used word/phrase once, and then reference it anywhere you need it!

General References (REF)

General references are defined in a language file using double curly braces with a REF: prefix like so: {{REF:myCategory.myItem}}, and are used to point to an item in the "refs" section of the language file.

Here is an example:

{
    "data": {
        "intro": {
            "myFavoriteColor": "My favorite color is {{REF:aboutMe.favoriteColor}}.",
            "yourFavoriteColor": "Is your favorite color {{REF:aboutMe.favoriteColor}} too?"
        }
    },
    "refs": {
        // This is a general reference category:
        "aboutMe": {
            // This is a general reference item:
            "favoriteColor": "purple"
        }
    }
}

And in the code:

let myFavoriteColor = linguini.get('intro.myFavoriteColor', 'en', TypeMappers.String);
console.log(myFavoriteColor);
// Outputs: "My favorite color is purple!"

let yourFavoriteColor = linguini.get('intro.yourFavoriteColor', 'en', TypeMappers.String);
console.log(yourFavoriteColor);
// Outputs: "Is your favorite color purple too?"

You can also retrieve a reference directly by using Linguini#getRef().

Common References (COM)

Common References are handy when you want to use the same word/phrase across multiple language files. For example, links are a good place to use Common References, since links are typically displayed alongside translated text, but often stay the same regardless of language.

To use Common References, create a file that matches your language file names, but use common as the language code. For example: lang.common.json.

In the common language file, you can define references like so:

{
    // This is a common reference category:
    "links": {
        // This is a common reference item:
        "github": "https://github.com/KevinNovak"
    }
}

Then in any language file, you can refer to a common reference by using using double curly braces with a COM: prefix like so: {{COM:myCategory.myItem}}.

So continuing with the above common file example, we can use this link in another language file like so:

{
    "data": {
        "aboutMe": {
            "myGitHub": "Follow me on GitHub at {{COM:links.github}}!"
        }
    },
    "refs": {}
}

And in the code:

let myGitHub = linguini.get('aboutMe.myGitHub', 'en', TypeMappers.String);
console.log(myGitHub);
// Outputs: "Follow me on GitHub at https://github.com/KevinNovak!"

You can also retrieve a common reference directly by using Linguini#getCom().