Skip to content

pureartisan/simple-i18n

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simple I18n npm version CircleCI

Simple and light weight i18n library.

Installation

npm install @pureartisan/simple-i18n

HTML tags in your translations

If you want to use HTML tags in your translations safely (without opening your application into XSS), you have to use a proper technic to parse the tags in the translation file.

You can use one of the plugins for "Simple I18n" below. Depending on the framework being used:

NOTE The above plugins are required ONLY if you want to use HTML tags in the translation files, otherwise you can simple use this module without your React/Angular/Vue projects.

Getting started

// ES5
var i18n = require('@pureartisan/simple-i18n');

// ES6
import i18n from '@pureartisan/simple-i18n';

// initialise once at the start
// NOTE: normally you'd want to define the languages and rules on separate files and import them here.

i18n.init({
  locale: 'en',
  languages: {
    'en': { ... },
    'en-uk': { ... },
    'en-us': { ... },
    'de': { ... },
    'fr': { ... }
  },
  rules: {
    'date': function() { ... },
    'custom': function() { ... }
  }
});

Translations

/*
sample language file entry
{
  'home-page.greeting': 'Hello'
}
*/
var translated1 = i18n.translate('home-page.greeting');

/*
sample language file entry
{
  'home-page.greeting': 'Hello {firstName}'
}
*/
var translated2 = i18n.translate('home-page.greeting', { firstName: 'Bob' });

Easy syntax

// ES5
var i18n = require('@pureartisan/simple-i18n');
var translate = i18n.translate;

// ES6
import { translate } from '@pureartisan/simple-i18n';

...

translate('greeting');

Locales

var languageDefinitions = { // loaded from files
  'common': {     // 'common' is shared with every different language and is used as a fallback
    'greeting': 'Hi'
  }
  'en': {
    'greeting': 'Hello'
  },
  'de': {
    'greeting': 'Hallo'
  }
};

i18n.init({
  languages: languageDefinitions,
  locale: 'en'
});

// translate now, will work with 'en'
i18n.translate('greeting'); // returns 'Hello'

// change to 'de'
i18n.setLocale('de');
i18n.translate('greeting'); // returns 'Hallo'

// change to 'fr' (not defined in languages)
i18n.setLocale('fr'); // this will default to 'common' locale
i18n.translate('greeting'); // returns 'Hi'

Rules

Rules are variable transforming functions, that takes in an object or string as a value, and the name of the variable and always returns a string.

function ( objectOrStringOption, nameOfVariable ) {
  return someTransformedString;
}

Example:

language file entry:
...
'animal-count-statement': 'I have {count,number} {animal,singular-plural}'
...

var rules = {
  'number': function(value, name) {
     return Math.floor(value).toString();
   },
   'singular-plural': function(obj, name) { // you can define the shape of this 'obj' according to your custom rule
      var amount = obj.number;
      var labelWhenSingular = obj.sinuglar;
      var labelWhenPlural = obj.plural;
      return amount === 1 ? labelWhenSingular : labelWhenPlural;
   }
}

// calling the translation as below,
// remember we need to provide the variables 'count' and 'animal' according to the above language file:
// 'I have {count,number} {animal,singular-plural}'

var numCats = 5;
var catArgs = {
  count: numCats,
  animal: {
    // remember the custom rule for 'singular-plural'
    number: numCats,
    singular: 'cat',
    plural: 'cats'
  }
};

var numDogs = 1;
var dogArgs = {
  count: numDogs,
  animal: {
    // remember the custom rule for 'singular-plural'
    number: numDogs,
    singular: 'dog',
    plural: 'dogs'
  }
};

i18n.translate('animal-count-statement', catArgs); // returns 'I have 5 cats'
i18n.translate('animal-count-statement', dogArgs); // returns 'I have 1 dog'

Locale dependant rules

We may sometimes need rules dependent on locale, such as different date formats

import moment from 'moment';

...

var languageDefinitions = {
  'common': {
    'greeting.today': 'Hi, today is {today,date}' // 'today' is the variable name, 'date' is the rule name
  },
  'en': {
    'date-format': 'DD-MM-YYYY'
  },
  'de': {
    'date-format': 'DD.MM.YYYY'
  }
};

var rules = {
  'date': function(value, name) {
     var dateFormat = i18n.raw('date-format'); // this will be resolved using the current locale
     return moment(value).format(dateFormat);
   }
}

i18n.init({
  languages: languageDefinitions,
  locale: 'en',
  rules: rules
});

...

// current locale is 'en'
i18n.translate('greeting.today', { today: new Date() }); // returns 'Hi, today is 12-11-2018'

// change to 'de'
i18n.setLocale('de');
i18n.translate('greeting.today'); // returns 'Hi, today is 12.11.2018'

Helpers

i18n.setLocale(locale)

You can override the locale using setLocal() method.

// locale; e.g. 'en', 'en-uk', 'de', 'fr'
function onUserChooseLanguage(locale) {
   i18n.setLocale(lanugage);
}

i18n.raw(i18nKey)

You can access the raw/unprocessed i18n translation, that will return a raw string (variables will not be replaced).

var languageDefinitions = {
  'common': {
    'greeting.today': 'Hi, today is {today,date}'
  }
}

...

i18n.raw(i18nKey); // returns 'Hi, today is {today,date}'

i18n.process(i18nKey, i18nOptions)

You can also use the manual rules processor (regardless of the current locale).

// taken from the above example of rules, you can directly call the 'process()' method
i18n.process('I have {count,number} {animal,singular-plural}', catArgs); // returns 'I have 5 cats'
i18n.process('She has {count,number} {animal,singular-plural}', dogArgs); // returns 'She has 1 dog'