README.md in i18n-js-3.9.2 vs README.md in i18n-js-4.0.0.alpha1
- old
+ new
@@ -1,1099 +1,142 @@
-<p align="center">
- <img width="250" height="58" src="https://github.com/fnando/i18n-js/raw/main/i18njs.png" alt="i18n.js">
-</p>
+# i18n-js
-<p align="center">
- It's a small library to provide the Rails I18n translations on the JavaScript.
-</p>
+[![Tests](https://github.com/fnando/i18n-js/workflows/ruby-tests/badge.svg)](https://github.com/fnando/i18n-js)
+[![Code Climate](https://codeclimate.com/github/fnando/i18n-js/badges/gpa.svg)](https://codeclimate.com/github/fnando/i18n-js)
+[![Gem](https://img.shields.io/gem/v/i18n-js.svg)](https://rubygems.org/gems/i18n-js)
+[![Gem](https://img.shields.io/gem/dt/i18n-js.svg)](https://rubygems.org/gems/i18n-js)
-<p align="center">
- <a href="https://github.com/fnando/i18n-js/actions?query=workflow%3ATests"><img src="https://github.com/fnando/i18n-js/workflows/Tests/badge.svg" alt="Tests"></a>
- <a href="https://badge.fury.io/rb/i18n-js"><img src="https://img.shields.io/gem/v/i18n-js.svg" alt="Gem Version"></a>
- <a href="https://www.npmjs.com/package/i18n-js"><img src="https://img.shields.io/npm/v/i18n-js.svg" alt="npm"></a>
- <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
- <a href="https://coveralls.io/r/fnando/i18n-js"><img src="https://img.shields.io/coveralls/fnando/i18n-js.svg" alt="Coverage Status"></a>
- <a href="https://gitter.im/fnando/i18n-js"><img src="https://img.shields.io/badge/gitter-join%20chat-1dce73.svg" alt="Gitter"></a>
-</p>
+Export [i18n](https://rubygems.org/gems/i18n) translations to JSON. A perfect
+fit if you want to export translations to JavaScript.
----
+Oh, you don't use Ruby? No problem! You can still use i18n-js and the
+[companion JavaScript package](https://npmjs.com/package/i18n-js).
-Features:
+## Installation
-- Pluralization
-- Date/Time localization
-- Number localization
-- Locale fallback
-- Asset pipeline support
-- Lots more! :)
+```bash
+gem install i18n-js
+```
-## Version Notice
+Or add the following line to your project's Gemfile:
-The `main` branch (including this README) is for latest `3.0.0` instead of
-`2.x`.
-
-## Usage
-
-### Installation
-
-#### Rails app
-
-Add the gem to your Gemfile.
-
```ruby
-gem "i18n-js"
+gem "i18n-js", "~> 4.0.0.alpha1"
```
-#### Rails with [webpacker](https://github.com/rails/webpacker)
+## Usage
-If you're using `webpacker`, you may need to add the dependencies to your client
-with:
+About patterns:
-```
-yarn add i18n-js
-# or, if you're using npm,
-npm install i18n-js
-```
+- Patterns can use `*` as a wildcard and can appear more than once.
+ - `*` will include everything
+ - `*.messages.*`
+- Patterns starting with `!` are excluded.
+ - `!*.activerecord.*` will exclude all ActiveRecord translations.
-For more details, see:
-- [this gist](https://gist.github.com/bazzel/ecdff4718962e57c2d5569cf01d332fe)
-- https://github.com/fnando/i18n-js/issues/597
+The config file:
-#### Rails app with [Asset Pipeline](https://guides.rubyonrails.org/asset_pipeline.html)
-
-If you're using the
-[asset pipeline](https://guides.rubyonrails.org/asset_pipeline.html), then you
-must add the following line to your `app/assets/javascripts/application.js`.
-
-```javascript
-//
-// This is optional (in case you have `I18n is not defined` error)
-// If you want to put this line, you must put it BEFORE `i18n/translations`
-//= require i18n
-// Some people even need to add the extension to make it work, see https://github.com/fnando/i18n-js/issues/283
-//= require i18n.js
-//
-// This is a must
-//= require i18n/translations
-```
-
-#### Rails app without [Asset Pipeline](https://guides.rubyonrails.org/asset_pipeline.html)
-
-First, put this in your `application.html` (layout file). Then get the JS files
-following the instructions below.
-
-```erb
-<%# This is just an example, you can put `i18n.js` and `translations.js` anywhere you like %>
-<%# Unlike the Asset Pipeline example, you need to require both **in order** %>
-<%= javascript_include_tag "i18n" %>
-<%= javascript_include_tag "translations", skip_pipeline: true %>
-```
-
-**There are two ways to get `translations.js` (For Rails app without Asset
-Pipeline).**
-
-1. This `translations.js` file can be automatically generated by the
- `I18n::JS::Middleware`. Just add `config.middleware.use I18n::JS::Middleware`
- to your `config/application.rb` file.
-2. If you can't or prefer not to generate this file, you can move the middleware
- line to your `config/environments/development.rb` file and run
- `rake i18n:js:export` before deploying. This will export all translation
- files, including the custom scopes you may have defined on
- `config/i18n-js.yml`. If `I18n.available_locales` is set (e.g. in your Rails
- `config/application.rb` file) then only the specified locales will be
- exported. Current version of `i18n.js` will also be exported to avoid version
- mismatching by downloading.
-
-#### Export Configuration (For translations)
-
-Exported translation files generated by `I18n::JS::Middleware` or
-`rake i18n:js:export` can be customized with config file `config/i18n-js.yml`
-(use `rails generate i18n:js:config` to create it). You can even get more files
-generated to different folders and with different translations to best suit your
-needs. The config file also affects developers using Asset Pipeline to require
-translations. Except the option `file`, since all translations are required by
-adding `//= require i18n/translations`.
-
-Examples:
-
-```yaml
+```yml
+---
translations:
- - file: "public/javascripts/path-to-your-messages-file.js"
- only: "*.date.formats"
- - file: "public/javascripts/path-to-your-second-file.js"
- only: ["*.activerecord", "*.admin.*.title"]
-```
+ - file: app/frontend/locales/en.json
+ patterns:
+ - "*"
+ - "!*.activerecord"
+ - "!*.errors"
+ - "!*.number.nth"
-If `only` is omitted all the translations will be saved. Also, make sure you add
-that initial `*`; it specifies that all languages will be exported. If you want
-to export only one language, you can do something like this:
-
-```yaml
-translations:
- - file: "public/javascripts/en.js"
- only: "en.*"
- - file: "public/javascripts/pt-BR.js"
- only: "pt-BR.*"
+ - file: app/frontend/locales/:locale.json
+ patterns:
+ - "*"
```
-Optionally, you can auto generate a translation file per available locale if you
-specify the `%{locale}` placeholder.
+The Ruby API:
-```yaml
-translations:
- - file: "public/javascripts/i18n/%{locale}.js"
- only: "*"
- - file: "public/javascripts/frontend/i18n/%{locale}.js"
- only: ["*.frontend", "*.users.*"]
-```
-
-You can also include ERB in your config file.
-
-```yaml
-translations:
-<% Widgets.each do |widget| %>
-- file: <%= "'#{widget.file}'" %>
- only: <%= "'#{widget.only}'" %>
-<% end %>
-```
-
-You are able to exclude certain phrases or whole groups of phrases by specifying
-the YAML key(s) in the `except` configuration option. The outputted JS
-translations file (exported or generated by the middleware) will omit any keys
-listed in `except` configuration param:
-
-```yaml
-translations:
- - except: ["*.active_admin", "*.ransack", "*.activerecord.errors"]
-```
-
-#### Export Configuration (For other things)
-
-- `I18n::JS.config_file_path` Expected Type: `String` Default:
- `config/i18n-js.yml` Behaviour: Try to read the config file from that location
-
-- `I18n::JS.export_i18n_js_dir_path` Expected Type: `String` Default:
- `public/javascripts` Behaviour:
-
- - Any `String`: considered as a relative path for a folder to `Rails.root` and
- export `i18n.js` to that folder for `rake i18n:js:export`
- - Any non-`String` (`nil`, `false`, `:none`, etc): Disable `i18n.js` exporting
-
-- `I18n::JS.sort_translation_keys` Expected Type: `Boolean` Default: `true`
- Behaviour:
-
- - Sets whether or not to deep sort all translation keys in order to generate
- identical output for the same translations
- - Set to true to ensure identical asset fingerprints for the asset pipeline
-
-- You may also set `export_i18n_js` and `sort_translation_keys` in your config
- file, e.g.:
-
-```yaml
-export_i18n_js: false
-# OR
-export_i18n_js: "my/path"
-
-sort_translation_keys: false
-
-translations:
- - ...
-```
-
-To find more examples on how to use the configuration file please refer to the
-tests.
-
-#### Fallbacks
-
-If you specify the `fallbacks` option, you will be able to fill missing
-translations with those inside fallback locale(s). Default value is `true`.
-
-Examples:
-
-```yaml
-fallbacks: true
-
-translations:
- - file: "public/javascripts/i18n/%{locale}.js"
- only: "*"
-```
-
-This will enable merging fallbacks into each file. (set to `false` to disable).
-If you use `I18n` with fallbacks, the fallbacks defined there will be used.
-Otherwise `I18n.default_locale` will be used.
-
-```yaml
-fallbacks: :de
-
-translations:
- - file: "public/javascripts/i18n/%{locale}.js"
- only: "*"
-```
-
-Here, the specified locale `:de` will be used as fallback for all locales.
-
-```yaml
-fallbacks:
- fr: ["de", "en"]
- de: "en"
-
-translations:
- - file: "public/javascripts/i18n/%{locale}.js"
- only: "*"
-```
-
-Fallbacks defined will be used, if not defined (e.g. `:pl`) `I18n.fallbacks` or
-`I18n.default_locale` will be used.
-
-```yaml
-fallbacks: :default_locale
-
-translations:
- - file: "public/javascripts/i18n/%{locale}.js"
- only: "*"
-```
-
-Setting the option to `:default_locale` will enforce the fallback to use the
-`I18n.default_locale`, ignoring `I18n.fallbacks`.
-
-Examples:
-
-```yaml
-fallbacks: false
-
-translations:
- - file: "public/javascripts/i18n/%{locale}.js"
- only: "*"
-```
-
-You must disable this feature by setting the option to `false`.
-
-To find more examples on how to use the configuration file please refer to the
-tests.
-
-#### Available locales
-
-By specifying option `js_available_locales` with a list of locales, this list
-would be used instead of default `I18n.available_locales` to generate translations.
-
-Example:
-
-```yaml
-js_available_locales: ["de", "en"]
-```
-
-#### Namespace
-
-Setting the `namespace` option will change the namespace of the output
-Javascript file to something other than `I18n`. This can be useful in
-no-conflict scenarios. Example:
-
-```yaml
-translations:
- - file: "public/javascripts/i18n/translations.js"
- namespace: "MyNamespace"
-```
-
-will create:
-
-```
-MyNamespace.translations || (MyNamespace.translations = {});
-MyNamespace.translations["en"] = { ... }
-```
-
-### Adding prefix & suffix to the translations file(s)
-
-Setting the `prefix: "import I18n from 'i18n-js';\n"` option will add the line
-at the beginning of the resultant translation file. This can be useful to use
-this gem with the [i18n-js](https://www.npmjs.com/package/i18n-js) npm package,
-which is quite useful to use it with webpack. The user should provide the
-semi-colon and the newline character if needed.
-
-For example:
-
-```yaml
-translations:
- - file: "public/javascripts/i18n/translations.js"
- prefix: "import I18n from 'i18n-js';\n"
-```
-
-will create:
-
-```
-import I18n from 'i18n-js';
-I18n.translations || (I18n.translations = {});
-```
-
-`suffix` option is added in https://github.com/fnando/i18n-js/pull/561.
-It's similar to `prefix` so won't explain it in details.
-
-#### Pretty Print
-
-Set the `pretty_print` option if you would like whitespace and indentation in
-your output file (default: false)
-
-```yaml
-translations:
- - file: "public/javascripts/i18n/translations.js"
- pretty_print: true
-```
-
-#### Javascript Deep Merge (:js_extend option)
-
-By default, the output file Javascript will call the `I18n.extend` method to
-ensure that newly loaded locale files are deep-merged with any locale data
-already in memory. To disable this either globally or per-file, set the
-`js_extend` option to false
-
-```yaml
-js_extend: false # this will disable Javascript I18n.extend globally
-translations:
- - file: "public/javascripts/i18n/translations.js"
- js_extend: false # this will disable Javascript I18n.extend for this file
-```
-
-#### Vanilla JavaScript
-
-Just add the `i18n.js` file to your page. You'll have to build the translations
-object by hand or using your favorite programming language. More info below.
-
-#### Via NPM with webpack and CommonJS
-
-Add the following line to your package.json dependencies where version is the
-version you want:
-
-```javascript
-"i18n-js": "{version_constraint}"
-
-// Or if you want unreleased version
-// npm install requires it to be the gzipped tarball, see [npm install](https://www.npmjs.org/doc/cli/npm-install.html)
-"i18n-js": "https://github.com/fnando/i18n-js/archive/{tag_name_or_branch_name_or_commit_sha}.tar.gz"
-```
-
-Run npm install then use via
-
-```javascript
-var i18n = require("i18n-js");
-```
-
-### Setting up
-
-You **don't** need to set up a thing. The default settings will work just okay.
-But if you want to split translations into several files or specify contexts,
-you can follow the rest of this setting up section.
-
-Set your locale is easy as
-
-```javascript
-I18n.defaultLocale = "pt-BR";
-I18n.locale = "pt-BR";
-I18n.currentLocale();
-// pt-BR
-```
-
-**NOTE:** You can now apply your configuration **before I18n** is loaded like
-this:
-
-```javascript
-I18n = {}; // You must define this object in top namespace, which should be `window`
-I18n.defaultLocale = "pt-BR";
-I18n.locale = "pt-BR";
-
-// Load I18n from `i18n.js`, `application.js` or whatever
-
-I18n.currentLocale();
-// pt-BR
-```
-
-In practice, you'll have something like the following in your
-`application.html.erb`:
-
-```erb
-<script type="text/javascript">
- I18n.defaultLocale = "<%= I18n.default_locale %>";
- I18n.locale = "<%= I18n.locale %>";
-</script>
-```
-
-You can use translate your messages:
-
-```javascript
-I18n.t("some.scoped.translation");
-// or translate with explicit setting of locale
-I18n.t("some.scoped.translation", { locale: "fr" });
-```
-
-You can also interpolate values:
-
-```javascript
-// You need the `translations` object setup first
-I18n.translations["en"] = {
- greeting: "Hello %{name}",
-};
-
-I18n.t("greeting", { name: "John Doe" });
-```
-
-You can set default values for missing scopes:
-
-```javascript
-// simple translation
-I18n.t("some.missing.scope", { defaultValue: "A default message" });
-
-// with interpolation
-I18n.t("noun", { defaultValue: "I'm a {{noun}}", noun: "Mac" });
-```
-
-You can also provide a list of default fallbacks for missing scopes:
-
-```javascript
-// As a scope
-I18n.t("some.missing.scope", { defaults: [{ scope: "some.existing.scope" }] });
-
-// As a simple translation
-I18n.t("some.missing.scope", { defaults: [{ message: "Some message" }] });
-```
-
-Default values must be provided as an array of hashes where the key is the type
-of translation desired, a `scope` or a `message`. The translation returned will
-be either the first scope recognized, or the first message defined.
-
-The translation will fallback to the `defaultValue` translation if no scope in
-`defaults` matches and if no default of type `message` is found.
-
-Translation fallback can be enabled by enabling the `I18n.fallbacks` option:
-
-```erb
-<script type="text/javascript">
- I18n.fallbacks = true;
-</script>
-```
-
-By default missing translations will first be looked for in less specific
-versions of the requested locale and if that fails by taking them from your
-`I18n.defaultLocale`.
-
-```javascript
-// if I18n.defaultLocale = "en" and translation doesn't exist
-// for I18n.locale = "de-DE" this key will be taken from "de" locale scope
-// or, if that also doesn't exist, from "en" locale scope
-I18n.t("some.missing.scope");
-```
-
-Custom fallback rules can also be specified for a particular language. There are
-three different ways of doing it so:
-
-```javascript
-I18n.locales.no = ["nb", "en"];
-I18n.locales.no = "nb";
-I18n.locales.no = function (locale) {
- return ["nb"];
-};
-```
-
-### Translation Missing Behaviour Control
-
-By default a missing translation will be displayed as
-
- [missing "name of scope" translation]
-
-While you are developing or if you do not want to provide a translation in the
-default language you can set
-
-```javascript
-I18n.missingBehaviour = "guess";
-```
-
-this will take the last section of your scope and guess the intended value.
-Camel case becomes lower cased text and underscores are replaced with space
-
- questionnaire.whatIsYourFavorite_ChristmasPresent
-
-becomes "what is your favorite Christmas present"
-
-#### Option `missingTranslationPrefix`
-
-In order to still detect untranslated strings, you can set
-`I18n.missingTranslationPrefix` to something like:
-
-```javascript
-I18n.missingTranslationPrefix = "EE: ";
-```
-
-And result will be:
-
-```javascript
-"EE: what is your favorite Christmas present";
-
-```
-
-This will help you doing automated tests against your localisation assets.
-
-#### Customize return when translation entry missing
-
-Some people prefer returning `null`/`undefined` for missing translation:
-
-```javascript
-I18n.missingTranslation = function (scope, options) {
- return undefined;
-};
-```
-
-### Option `defaultSeparator` (global) / `separator` (local)
-
-Default separator of translation key is `.` (dot)
-Meaning `I18n.t("scope.entry")` would search for translation entry `I18n.translations[locale].scope.entry`
-Using a different separator can be done either globally or locally.
-
-Globally: `I18n.defaultSeparator = newSeparator`
-Locally: `I18n.t("full_sentences|Server Busy. Please retry later", {separator: '|'})`
-
-### Pluralization
-
-Pluralization is possible as well and by default provides English rules:
-
-```javascript
-I18n.t("inbox.counting", { count: 10 }); // You have 10 messages
-```
-
-The sample above expects the following translation:
-
-```yaml
-en:
- inbox:
- counting:
- one: You have 1 new message
- other: You have {{count}} new messages
- zero: You have no messages
-```
-
-**NOTE:** Rails I18n recognizes the `zero` option.
-
-If you need special rules just define them for your language, for example
-Russian, just add a new pluralizer:
-
-```javascript
-I18n.pluralization["ru"] = function (count) {
- var key =
- count % 10 == 1 && count % 100 != 11
- ? "one"
- : [2, 3, 4].indexOf(count % 10) >= 0 &&
- [12, 13, 14].indexOf(count % 100) < 0
- ? "few"
- : count % 10 == 0 ||
- [5, 6, 7, 8, 9].indexOf(count % 10) >= 0 ||
- [11, 12, 13, 14].indexOf(count % 100) >= 0
- ? "many"
- : "other";
- return [key];
-};
-```
-
-You can find all rules on
-<https://unicode-org.github.io/cldr-staging/charts/37/supplemental/language_plural_rules.html>.
-
-If you're using the same scope over and over again, you may use the `scope`
-option.
-
-```javascript
-var options = { scope: "activerecord.attributes.user" };
-
-I18n.t("name", options);
-I18n.t("email", options);
-I18n.t("username", options);
-```
-
-You can also provide an array as scope.
-
-```javascript
-// use the greetings.hello scope
-I18n.t(["greetings", "hello"]);
-```
-
-#### Number formatting
-
-Similar to Rails helpers, you have localized number and currency formatting.
-
-```javascript
-I18n.l("currency", 1990.99);
-// $1,990.99
-
-I18n.l("number", 1990.99);
-// 1,990.99
-
-I18n.l("percentage", 123.45);
-// 123.450%
-```
-
-To have more control over number formatting, you can use the `I18n.toNumber`,
-`I18n.toPercentage`, `I18n.toCurrency` and `I18n.toHumanSize` functions.
-
-```javascript
-I18n.toNumber(1000); // 1,000.000
-I18n.toCurrency(1000); // $1,000.00
-I18n.toPercentage(100); // 100.000%
-```
-
-The `toNumber` and `toPercentage` functions accept the following options:
-
-- `precision`: defaults to `3`
-- `separator`: defaults to `.`
-- `delimiter`: defaults to `,`
-- `strip_insignificant_zeros`: defaults to `false`
-
-See some number formatting examples:
-
-```javascript
-I18n.toNumber(1000, { precision: 0 }); // 1,000
-I18n.toNumber(1000, { delimiter: ".", separator: "," }); // 1.000,000
-I18n.toNumber(1000, { delimiter: ".", precision: 0 }); // 1.000
-```
-
-The `toCurrency` function accepts the following options:
-
-- `precision`: sets the level of precision
-- `separator`: sets the separator between the units
-- `delimiter`: sets the thousands delimiter
-- `format`: sets the format of the output string
-- `unit`: sets the denomination of the currency
-- `strip_insignificant_zeros`: defaults to `false`
-- `sign_first`: defaults to `true`
-
-You can provide only the options you want to override:
-
-```javascript
-I18n.toCurrency(1000, { precision: 0 }); // $1,000
-```
-
-The `toHumanSize` function accepts the following options:
-
-- `precision`: defaults to `1`
-- `separator`: defaults to `.`
-- `delimiter`: defaults to `""`
-- `strip_insignificant_zeros`: defaults to `false`
-- `format`: defaults to `%n%u`
-- `scope`: defaults to `""`
-
-<!---->
-
-```javascript
-I18n.toHumanSize(1234); // 1KB
-I18n.toHumanSize(1234 * 1024); // 1MB
-```
-
-#### Date formatting
-
-```javascript
-// accepted formats
-I18n.l("date.formats.short", "2009-09-18"); // yyyy-mm-dd
-I18n.l("time.formats.short", "2009-09-18 23:12:43"); // yyyy-mm-dd hh:mm:ss
-I18n.l("time.formats.short", "2009-11-09T18:10:34"); // JSON format with local Timezone (part of ISO-8601)
-I18n.l("time.formats.short", "2009-11-09T18:10:34Z"); // JSON format in UTC (part of ISO-8601)
-I18n.l("date.formats.short", 1251862029000); // Epoch time
-I18n.l("date.formats.short", "09/18/2009"); // mm/dd/yyyy
-I18n.l("date.formats.short", new Date()); // Date object
-```
-
-You can also add placeholders to the date format:
-
-```javascript
-I18n.translations["en"] = {
- date: {
- formats: {
- ordinal_day: "%B %{day}",
- },
- },
-};
-
-I18n.l("date.formats.ordinal_day", "2009-09-18", { day: "18th" }); // Sep 18th
-```
-
-If you prefer, you can use the `I18n.toTime` and `I18n.strftime` functions to
-format dates.
-
-```javascript
-var date = new Date();
-I18n.toTime("date.formats.short", "2009-09-18");
-I18n.toTime("date.formats.short", date);
-I18n.strftime(date, "%d/%m/%Y");
-```
-
-The accepted formats for `I18n.strftime` are:
-
- %a - The abbreviated weekday name (Sun)
- %A - The full weekday name (Sunday)
- %b - The abbreviated month name (Jan)
- %B - The full month name (January)
- %c - The preferred local date and time representation
- %d - Day of the month (01..31)
- %-d - Day of the month (1..31)
- %H - Hour of the day, 24-hour clock (00..23)
- %-H/%k - Hour of the day, 24-hour clock (0..23)
- %I - Hour of the day, 12-hour clock (01..12)
- %-I/%l - Hour of the day, 12-hour clock (1..12)
- %m - Month of the year (01..12)
- %-m - Month of the year (1..12)
- %M - Minute of the hour (00..59)
- %-M - Minute of the hour (0..59)
- %p - Meridian indicator (AM or PM)
- %P - Meridian indicator (am or pm)
- %S - Second of the minute (00..60)
- %-S - Second of the minute (0..60)
- %w - Day of the week (Sunday is 0, 0..6)
- %y - Year without a century (00..99)
- %-y - Year without a century (0..99)
- %Y - Year with century
- %z/%Z - Timezone offset (+0545)
-
-Check out `spec/*.spec.js` files for more examples!
-
-#### Using pluralization and number formatting together
-
-Sometimes you might want to display translation with formatted number, like
-adding thousand delimiters to displayed number You can do this:
-
-```json
-{
- "en": {
- "point": {
- "one": "1 Point",
- "other": "{{formatted_number}} Points",
- "zero": "0 Points"
- }
- }
-}
-```
-
-```js
-var point_in_number = 1000;
-I18n.t("point", {
- count: point_in_number,
- formatted_number: I18n.toNumber(point_in_number),
-});
-```
-
-Output should be `1,000 points`
-
-## Using multiple exported translation files on a page.
-
-This method is useful for very large apps where a single contained
-translations.js file is not desirable. Examples would be a global translations
-file and a more specific route translation file.
-
-### Rails without asset pipeline
-
-1. Setup your `config/i18n-js.yml` to have multiple files and try to minimize
- any overlap.
-
-```yaml
-sort_translation_keys: true
-fallbacks: false
-
-translations:
- + file: "app/assets/javascript/nls/welcome.js"
- only:
- + '*.welcome.*'
-
- + file: "app/assets/javascript/nls/albums.js"
- only:
- + '*.albums.*'
-
- + file: "app/assets/javascript/nls/global.js"
- only:
- + '*'
- # Exempt any routes specific translations from being
- # included in the global translation file
- except:
- + '*.welcome.*'
- + '*.albums.*'
-```
-
-When `rake i18n:js:export` is executed it will create 3 translations files that
-can be loaded via the `javascript_include_tag`
-
-2. Add the `javascript_include_tag` to your layout and to any route specific
- files that will require it.
-
```ruby
- # views/layouts/application.html.erb
- <%= javascript_include_tag(
- "i18n"
- "nls/global"
- ) %>
-```
+require "i18n-js"
-and in the route specific
-
-```ruby
- # views/welcome/index.html.erb
- <%= javascript_include_tag(
- "nls/welcome"
- ) %>
+I18nJS.call(config_file: "config/i18n.yml")
+I18nJS.call(config: config)
```
-3. Make sure that you add these files to your `config/application.rb`
+The CLI API:
-```ruby
- config.assets.precompile += %w(
- i18n
- nls/*
- )
+```console
+$ i18n init --config config/i18n.yml
+$ i18n export --config config/i18n.yml --require config/environment.rb
```
-### Using require.js / r.js
+By default, `i18n` will use `config/i18n.yml` and `config/environment.rb` as the
+configuration files. If you don't have these files, then you'll need to specify
+both `--config` and `--require`.
-To use this with require.js we are only going to change a few things from above.
+## Automatically export translations
-1. In your `config/i18n-js.yml` we need to add a better location for the i18n to
- be exported to. You want to use this location so that it can be properly
- precompiled by r.js.
+### Using guard
-```yaml
-export_i18n_js: "app/assets/javascript/nls"
-```
+Install [guard](https://rubygems.org/packages/guard) and
+[guard-compat](https://rubygems.org/packages/guard-compat). Then create a
+Guardfile with the following configuration:
-2. In your `config/require.yml` we need to add a map, shim all the translations,
- and include them into the appropriate modules
-
-```yaml
-# In your maps add (if you do not have this you will need to add it)
-map:
- '*':
- i18n: 'nls/i18n'
-
-# In your shims
-shims:
- nls/welcome:
- deps:
- + i18n
-
- nls/global:
- deps:
- + i18n
-
-# Finally in your modules
-modules:
- + name: 'application'
- include:
- + i18n
- + 'nls/global'
-
- + name: 'welcome'
- exclude:
- + application
- include:
- + 'nls/welcome'
-```
-
-3. When `rake assets:precompile` is executed it will optimize the translations
- into the correct modules so they are loaded with their assigned module, and
- loading them with requirejs is as simple as requiring any other shim.
-
-```javascript
-define(["welcome/other_asset", "nls/welcome"], function (otherAsset) {
- // ...
-});
-```
-
-4. (optional) As an additional configuration we can make a task to be run before
- the requirejs optimizer. This will allow any automated scripts that run the
- requirejs optimizer to export the strings before we run r.js.
-
-```rake
-# lib/tasks/i18n.rake
-Rake::Task[:'i18n:js:export'].prerequisites.clear
-task :'i18n:js:export' => :'i18n:js:before_export'
-task :'requirejs:precompile:external' => :'i18n:js:export'
-
-namespace :i18n do
- namespace :js do
- task :before_export => :'assets:environment' do
- I18n.load_path += Dir[Rails.root.join('config', 'locales', '*.{yml,rb}')]
- I18n.backend.load_translations
- end
- end
+```ruby
+guard(:"i18n-js",
+ run_on_start: true,
+ config_file: "./config/i18n.yml",
+ require_file: "./config/environment.rb") do
+ watch(%r{^(app|config)/locales/.+\.(yml|po)$})
+ watch(%r{^config/i18n.yml$})
+ watch("Gemfile")
end
```
-## Using I18n.js with other languages (Python, PHP, ...)
+If you files in a different location, the remember to configure file paths
+accordingly.
-The JavaScript library is language agnostic; so you can use it with PHP, Python,
-[your favorite language here]. The only requirement is that you need to set the
-`translations` attribute like following:
+Now you can run `guard start -i`.
-```javascript
-I18n.translations = {};
+### Using listen
-I18n.translations["en"] = {
- message: "Some special message for you",
-};
+Create a file under `config/initializers/i18n.rb` with the following content:
-I18n.translations["pt-BR"] = {
- message: "Uma mensagem especial para vocĂȘ",
-};
-```
-
-## Known Issues
-
-### Missing translations in precompiled file(s) after adding any new locale file
-
-Due to the design of `sprockets`:
-
-- `depend_on` only takes file paths, not directory paths
-- registered `preprocessors` are only run when the fingerprint of any asset
- file, including `.erb` files, is changed
-
-This means that new locale files will not be detected, and so they will not
-trigger a i18n-js refresh. There are a few approaches to work around this:
-
-1. You can force i18n-js to update its translations by completely clearing the
- assets cache. Use one of the following:
-
-```bash
-$ rake assets:clobber
-# Or, with older versions of Rails:
-$ rake tmp:cache:clear
-```
-
-These commands will remove _all_ fingerprinted assets, and you will have to
-recompile them with
-
-```bash
-$ rake assets:precompile
-```
-
-or similar commands. If you are precompiling assets on the target machine(s),
-cached pages may be broken by this, so they will need to be refreshed.
-
-2. You can change something in a different locale file.
-
-3. Finally, you can change `config.assets.version`.
-
-**Note:** See issue [#213](https://github.com/fnando/i18n-js/issues/213) for
-more details and discussion of this issue.
-
-### Translations in JS are not updated when Sprockets not loaded before this gem
-
-The "rails engine" declaration will try to detect existence of "sprockets"
-before adding the initailizer If sprockets is loaded after this gem, the
-preprocessor for making JS translations file cache to depend on content of
-locale files will not be hooked. So ensure sprockets is loaded before this gem
-by moving the entry of sprockets in the Gemfile or adding "require" statements
-for sprockets somewhere.
-
-**Note:** See issue [#404](https://github.com/fnando/i18n-js/issues/404) for
-more details and discussion of this issue.
-
-### JS `I18n.toCurrency` & `I18n.toNumber` cannot handle large integers
-
-The above methods use `toFixed` and it only supports 53 bit integers. Ref:
-https://2ality.com/2012/07/large-integers.html
-
-Feel free to find & discuss possible solution(s) at issue
-[#511](https://github.com/fnando/i18n-js/issues/511)
-
-### May not work with all backend implementations
-
-I18n backend implementations have to conform to a specific interface to work
-with i18n-js. For backends that do not conform to the interface, you will likely
-get an exception like this:
-
-```
-Undefined method 'initialized?' for <your backend class>
-```
-
-For now, i18n-js is compatible with the `Simple` backend and with
-`I18n::Backend::ActiveRecord` (>= 0.4.0).
-
-If you need a more sophisticated backend for your rails application that doesn't
-implement the required methods, you can setup i18n-js to get translations from a
-separate `Simple` backend, by adding the following in an initializer:
-
```ruby
-I18n::JS.backend = I18n.backend
-I18n.backend = I18n::Backend::Chain.new(<your other backend(s)>, I18n.backend)
-```
+# frozen_string_literal: true
-This will use your backend with the default `Simple` backend as fallback, while
-i18n-js only sees and uses the simple backend. This means however, that only
-translations from your static locale files will be present in JavaScript.
+require "i18n-js/listen"
-If you do cannot use a `Chain`-Backend for some reason, you can also set
-
-```ruby
-I18n::JS.backend = I18n::Backend::Simple.new
-I18n.backend = <something different>
+I18nJS.listen
```
-However, the automatic reloading of translations in developement will not work
-in this case. This is because Rails calls `I18n.reload!` for each request in
-development, but `reload!` will not be called on `I18n::JS.backend`, since it is
-a different object. One option would be to patch `I18n.reload!` in an
-initializer:
+The code above will watch for changes based on `config/i18n.yml` and
+`config/locales`. You can customize these options with
+`I18nJS.listen(config_file: "config/i18n.yml", locales_dir: "config/locales")`.
-```ruby
-module I18n
- def self.reload!
- I18n::JS.backend.reload!
- super
- end
-end
-```
+### Integrating with your frontend
-See issue [#428](https://github.com/fnando/i18n-js/issues/428) for more details
-and discussion of this issue.
+You're done exporting files, now what? Well, go to
+[i18n](https://github.com/fnando/i18n) to discover how to use the NPM package
+that loads all the exported translation.
## Maintainer
-- Nando Vieira - <https://nandovieira.com>
+- [Nando Vieira](https://github.com/fnando)
-## Contributing
+## Contributors
-Once you've made your great commits:
+- https://github.com/fnando/i18n-js/contributors
-1. [Fork](https://help.github.com/forking/) I18n.js
-2. Create a branch with a clear name
-3. Make your changes (Please also add/change spec, README and CHANGELOG if
- applicable)
-4. Push changes to the created branch
-5. [Create an Pull Request](https://github.com/fnando/i18n-js/pulls)
-6. That's it!
+## Contributing
-Please respect the indentation rules and code style. And use 2 spaces, not tabs.
-And don't touch the versioning thing.
+For more details about how to contribute, please read
+https://github.com/fnando/i18n-js/blob/main/CONTRIBUTING.md.
-## Running tests
-
-You can run I18n tests using Node.js or your browser.
-
-To use Node.js, install the `jasmine-node` library:
-
- $ npm install jasmine-node
-
-Then execute the following command from the lib's root directory:
-
- $ npm test
-
-To run using your browser, just open the `spec/js/specs.html` file.
-
-You can run both Ruby and JavaScript specs with `rake spec`.
-
## License
-(The MIT License)
+The gem is available as open source under the terms of the
+[MIT License](https://opensource.org/licenses/MIT). A copy of the license can be
+found at https://github.com/fnando/i18n-js/blob/main/LICENSE.md.
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the 'Software'), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
+## Code of Conduct
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+Everyone interacting in the i18n-js project's codebases, issue trackers, chat
+rooms and mailing lists is expected to follow the
+[code of conduct](https://github.com/fnando/i18n-js/blob/main/CODE_OF_CONDUCT.md).