npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

railsy-i18n

v0.3.3

Published

Node.js adaptation of Ruby I18n library

Downloads

9

Readme

railsy-i18n

Node.js adaptation of Ruby I18n library

Main goal of this project is to provide an easy way of using Ruby I18n conventions in node applications.

It is intended to be a simple, flexible library for internationalization and localization which can be used as a standalone solution or/and easen the transfer of translation files from Rails backend to any node environment.

Installation

npm i railsy-i18n

Example Usage

const I18n = require("railsy-i18n");

let enI18n = new I18n({
  en: {
    users_count: {
      zero: "No users",
      one: "One user",
      other: "%{count} users"
    },
    header: {
      login: "Log me in",
      signup: "Sign me up",
      welcome: "Welcome, %{name}"
    },
  }
}, { scope: "en" });

// Basic usage
enI18n.t("header.login"); //=> "Log me in"
enI18n.t("header.welcome", {name: "John"}); //=> "Welcome, John"

// Pluralization
enI18n.t("users_count", { count: 4} ); //=> "4 users"
enI18n.t("users_count", { count: 0} ); //=> "No users"

// Missing translations
enI18n.t("header.missing_translation"); //=> "Missing translation"

// I18n#scoped method
let headerT = enI18n.scoped("header");
headerT("welcome", {name: "John"}); //= "Welcome, John"

// fallbacks
let ruI18n = new I18n({
  ru: {
    header: {
      login: "Войти",
    },
  }
}, { scope: "ru", fallbackI18n: enI18n });

ruI18n.t("header.login"); //=> "Войти"
ruI18n.t("header.welcome", {name: "Джон"}); //=> "Welcome, Джон"

API

Constructor options

new I18n(translations[, options])
  • translations: an object, containing all translations for this instance. Required.
  • options.scope: a string, default scope for all translations. Optiona.
  • options.fallbackI18n: an I18n instance to which all missing translations will be delegated. Optional.
  • options.pluralizationRule: a function. See Pluralization section for more details. Optional.

I18n#t method

enI18n.t(path[, interpolationVariables])
  • path: a string, path to translation in 'path.to.translation' format
  • interpolationVariables: an object of placeholder replacements in the translation string.

If translation is not a string, this method will return a humanized string based on the translation path. For example:

const I18n = require("railsy-i18n");

let i18n = new I18n({foo: "foo %{bar}, %{baz}"});

// Extra interpolation variables are ignored
i18n.t("foo", {bar: "bazzz", baz: "barrr", ignored: "123"}); //=> "foo bazzz, barrr"

// Missing translations
i18n.t("foo.bar.baz"); //=> "Baz"

I18n#scoped method

Returns a wrapper function which delegates to I18n#t with appended scope.

  • scope: a string

Example:

const I18n = require("railsy-i18n");

let i18n = new I18n({foo: {bar: "scoped bar"}});

let t = i18n.scoped("foo");

t("bar"); //=> "scoped bar"

Pluralization

count key in I18n#t interpolationVariables object has a special meaning. If translation at path is an object and count is present, railsy-i18n will try to search this object for a corresponding key based on the provided(or default) pluralizationRule function(see Constructor options). Default rule looks like this:

function defaultPluralizationRule(count) {
  if (count === 0) {
    return "zero";
  } else if (count === 1) {
    return "one";
  } else {
    return "other";
  }
}

As you can see, it simply returns a key which is then used to determine correct translation string. %{count} placeholder is also replaced inside this string if necessary. It's completely up to you which keys to use, but common conventions are "zero", "one", "few" and "other". The only assumption railsy-i18n makes about these keys is that 'zero' key is optional and can replaced with 'other'. Some examples:

Default rule:

const I18n = require("railsy-i18n");

let defaultI18n = new I18n({
  users: {
    one: "One user",
    other: "%{count} users"
  },
  items: "%{count} items"
});

// Note how `users.other` is used in this case and not `users.zero`(which is undefined)
defaultI18n.t("users", {count: 0}); //=> "0 users"

defaultI18n.t("users", {count: 1}); //=> "One user"
defaultI18n.t("users", {count: 312}); //=> "312 users"

// 
defaultI18n.t("items", {count: 1}); //=> "1 items"

Custom rules:

const I18n = require("railsy-i18n");

let myRule = (count) => {
  if (count === 0) {
    // It's also possible use an array of keys
    return ["my_zero", "my_zero2"];
  } else if (count === 1) {
    return "my_one";
  } else {
    return "something_else";
  }
};

let customI18n = new I18n({
  users: {
    my_zero: "My Zero users",
    my_one: "My One user",
    something_else: "My %{count} users"
  },
  items: {
    my_zero2: "My Zero2 items"
  }
}, { pluralizationRule: myRule });

customI18n.t("users", {count: 0}); //=> "My Zero users"
customI18n.t("users", {count: 1}); //=> "My One user"
customI18n.t("users", {count: 312}); //=> "My 312 users"

customI18n.t("items", {count: 0}); //=> "My Zero2 items"

I18n.Strict

This package also provides a Strict version of I18n class which throws an error if one of the following occurs:

  1. Translation cannot be found or is not a string.
  2. Some of the placeholders in translation string are not replaced.
  3. Some of the interpolationVariables are undefined.

The only intended use of I18n.Strict is testing, do not use it in production environments!

Example usage:

const I18n = require("railsy-i18n");

let strict = new I18n.Strict({
  page: {
    title: "%{text} Page"
  },

  users: {
    one: "One user"
  },
  items: "%{count} items"
});

// Throws: Translation missing: t("title", {})
strict.t("title");

// Throws: Missing interpolation variables: expected to receive {text} for "%{text} Page", but got: t("page.title", {})
strict.t("page.title");

// Throws: Encountered undefined interpolation variables for t("page.title", { text: undefined })
strict.t("page.title", {text: undefined});

// Returns correct string if there are no errors
strict.t("page.title", { text: "Home" }); //=> Home Page

// Throws: Translation missing: t("users", { count: 0 })
strict.t("users", { count: 0 } );

License

MIT