ICU MessageFormat for Javascript - i18n Plural and Gender Capable Messages

Overview

messageformat

The experience and subtlety of your program's text can be important. Messageformat is a mechanism for handling both pluralization and gender in your applications. It can also lead to much better translations, as it's designed to support all the languages included in the Unicode CLDR.

This monorepo consists of the following packages that make up our JS implementation of ICU MessageFormat:

Getting Started

Depending on your situation, consult one or more of the following guides:

Alternatively, take a look at our examples or dig into the API documentation if you're looking to do something more involved.

Our Format Guide will help with the ICU MessageFormat Syntax, and the Usage Guide provides some further options for integrating messageformat to be a part of your workflow around UI texts and translations.


Messageformat is an OpenJS Foundation project, and we follow its Code of Conduct.

OpenJS Foundation
Comments
  • Integration with Handlebars and RequireJS

    Integration with Handlebars and RequireJS

    I'm starting a new project and I intend to implement internationalization using the library. I'd also like to integrate messageformat.js with Handlebars and I found some references to this in the documentation. Is there any ETA on the implementation?

    I could try to do it myself, but I'd need some indications on where to start to do it right.

    Thanks in advance!

    opened by lrlopez 26
  • PluralFormat decimals handling

    PluralFormat decimals handling

    Hello

    I have to format a string including a number of hours and a label (in french) : {HOURS, plural, one{# heure} other{# heures}} giving me well formated string with integers : 0 heure 1 heure 2 heures

    Problem is that when I have a decimal value between 0 and 1, it displays : 0.5 heures instead of 0.5 heure

    I tried with zero{} and =0{} without success, it falls back automatically in the other{} format. I didn't find any <1{} syntax. How can I do that ?

    ps: I could use the SelectFormat syntax with a new boolean variable telling me wether HOURS is a decimal between 0 and 1 ... but is there a more elegant solution ? Thanks

    opened by jscti 21
  • messageformat.js: Provide Bidi Text Direction and Structured Text support to MessageFormat

    messageformat.js: Provide Bidi Text Direction and Structured Text support to MessageFormat

    As per discussion under #539 Message formatting dependant on base text direction I am submitting here the addition of predefined number formatting function enforcing Bidi Text Direction and Structured Text by using UCC. The upgrading qualities are:

    • Prevents intermingling of text contained in placeholders with the rest of message text.
    • Maintains the integrity of Bidi text flowing according to directionality of language script.
    • Enforces 'contextual' Bidi text direction on placeholder content
    • i.e. text direction is defined by first strong character of placeholder text -
    • 'right-to-left' if first strong character is bidi (Hebrew/Arabic) and 'left-to-right' othervise.
    • For reference to Bidi strucctured text see: http://cldr.unicode.org/development/development-process/design-proposals/bidi-handling-of-structured-text
    • For reference to Bidi text direction see: http://w3-03.ibm.com/globalization/page/publish/4353

    Please note that this submission constitutes the first step, the next would to be step is contribution to Globalize (https://github.com/jquery/globalize) with objective to make this Bidi formatter available for Globalize.messageFormatter. The intended contribution to Globalize is to:

    • add parameter (object containing formatters) to 'messageFormatter' API and pass it to 'MessageFormat' Globalize.prototype.messageFormatter = function( path, fmt ) { .................... formatter = new MessageFormat( cldr.locale, pluralGenerator, fmt ).compile( message );
    • expose predefined formatters Globalize.prototype.messageFormatter.formatters = MessageFormat.formatters;
    opened by ashensis 17
  • Consider Strawman Draft API?

    Consider Strawman Draft API?

    If you are open to changing your API slightly (approximating to Strawman Draft)'s, we could have something like the below.

    var messageFormat = new MessageFormat( locale, pattern [, fieldFormatters] );
    var formattedMessage = messageFormat.format( params );
    
    • locale is a string locale. E.g., en. (no changes to what you currently have)
    • pattern is the message-format pattern. E.g., {count, plural, one{...} other{...}}. (no changes to what you currently have)
    • fieldFormatters a key-value pair of fns. E.g., { plural: <fn>, number: <fn> }. (it extends the way you currently get plural)

    The optional fieldFormatters could be merged with a static/global/default one, e.g., MessageFormat._fieldFormatters.<locale>. So, you can keep setting the default plural function for English on your bundle.

    Production mode (precompilation)

    A formatted message is (obviously) a result of the generated formatter, which is the compiled pattern processed by two set of functions: (a) [runtime functions](what's currently been called .functions%28%29) and (b) the fields functions (currently, the plural function).

    The generated formatter doesn't embed the runtime functions nor the fields functions (which also makes sense to me). So, we can say the generated formatter is a function that depends on both of them:

    messageFormat.precompile(); // => function( runtimeFns, fieldsFns ) {
    //  return <the generated formatter( params )>;
    //}
    

    The runtime bundle

    Having distinguished the three layers above, generating the runtime bundle is not difficult. It could be accomplished in a variety of different ways:

    Or:

    <script src="messageformat.runtime.js"></script>
    <script src="my-plural.runtime.js"></script>
    <script>
      MyGlobalName[ "key" ] = <precompiled>( MessageFormat, { plural: myPlural } );
    </script>
    

    Or:

    // app.js
    require.config({
      paths: {
        messageformat: "messageformat.runtime"
        "my-plural": "my-plural.runtime"
      }
    });
    
    require([ "./my-precompiled-message-formatter" ], function( messageFormatter ) {
      var message = messageFormatter({ count: 1 });
    });
    
    // my-precompiled-message-formatter.js
    define([ "messageformat", "my-plural" ], function( MessageFormat, myPlural ) {
      return <precompiled>( MessageFormat, { plural: myPlural } );
    });
    

    OBS:

    It's the plural library problem to generate its own plural runtime. The same way, it's the number formatter problem to generate its own runtime, the same for date formatter, currency formatter, etc.

    documentation 
    opened by rxaviers 17
  • Refactor everything

    Refactor everything

    So, I may have ended up going down a bit of a rabbit hole when I fixed #134 while thinking of #132, and put together this little proposed set of changes. It includes changes to, well, nearly everything except for the parser. The source code documents itself pretty well, but here's an overview of the changes:

    Constructor

    Takes in a single locale parameter, which can be a string, array or object; the last form effectively includes the functionality of the previous second parameter pluralFunc. The semantics of locale are also a little different, as the concept of fallback locales is dropped, and instead having multiple entries creates a fully multi-lingual MessageFormat object. The formatters are dropped from the constructor; their addition is now with a chainable addFormatters method. They're also much better documented.

    compile()

    With object input, the output is no longer a function, but an object with a similar structure as the input, with each messageformatted string replaced by a corresponding function. The top-level object has a toString method that works a bit like previously, except better -- it defaults to an UMD wrapper, and can output e.g. ES6 module code. When used with multiple locales, the locale is auto-detected from the object keys. The second optional parameter locale can be used to force a single locale, or to select one if the constructor was originally called with no parameters.

    Runtime

    The included runtime methods are flattened, and only included if actually used. See the updated example for the new default output, and note that it's missing the select function as that's not included in any of the compiled functions. The flattening does mean that some locale names need to be fiddled with to make them valid non-reserved JS function names.

    bin/messageformat.js

    Effectively completely rewritten and simplified, given the new compile().toString() output and options.


    Altogether, this is a whole pile of breaking changes, and will need a new major version. Perhaps it'd be time to consider a 1.0 release?

    opened by eemeli 16
  • Build a tool to support translators based on messageformat.js?

    Build a tool to support translators based on messageformat.js?

    I need to support some translators with writing nested select and pluralization rules. One option we're looking into would be to have a JavaScript-based app where they can put their message into a text form and would get one or more of the following:

    • Syntax check: Is their message valid? If not, can we tell them where it's broken or can we fix it automatically?
    • Pretty printing: For example, indentations for nested selects. Or highlighting of fixed string parts (like we developers are used from IDEs)
    • Testing: Can we automatically extract all the variables used in a message and allow users to provide values for them (or select radio controls for different "select" cases) so they can then get a live-preview of what the resulting message would be?

    Would messageformat.js be a good base for building such a tool? Can it already produce the necessary information by parsing the message strings?

    Do you know of any other libraries (or off-the-shelf tools) that could help me solve this?

    Thanks!

    external-tooling 
    opened by mpdude 14
  • Tooling to maintain JSON files ?

    Tooling to maintain JSON files ?

    Well, it's more a general question than a real issue.

    I currently use a JavaScript implementation of Gettext in my project and plan to switch to messageformat.js.

    In the Gettext world it's rather easy to edit translations :

    • both the original and translated strings are in the same file
    • Poedit eases the process when working with independent translators
    • merging po files can be done with msgmerge...

    My problem: in my test with messageformat, I have two JSON files (french and english translations). It makes the translation process harder since I have to switch between those files to check what's written in french or in english.

    I would like to know that king of workflow/tool are used to keep the JSON files up-to-date (more specifically when working with independent translators).

    Thanks for making messageformat =)

    Benoit

    external-tooling 
    opened by bhirbec 14
  • Add ICU simpleArg support

    Add ICU simpleArg support

    This is a follow-up to discussion in #65, and it implements ICU's simpleArg syntax in a rather liberal fashion. Effectively, it makes syntax like {var, fn[, args]*} call a user-definable function fn, passing it the value of var, the locale(s), and args.

    Formatting functions for ICU's number, date and time are included, making use of Intl.NumberFormat and Intl.DateTimeFormat. They are a part of ECMA-402, but are not yet available in node by default (see joyent/node#7676), though their support in browsers is getting to be pretty good. There is a node polyfill available, though.

    The spellout, ordinal and duration argTypes are not supported, as they're way more complicated and without support via Intl or in fact any JavaScript library that I could find. ICU uses the rules defined here using this syntax to manage them, and implementing all that in JavaScript probably ought to stay outside the scope of messageformat.js.

    As number includes the argStyle currency, it currently defaults to USD. To use something else, you should set mf.currency before calling mf.compile(), like so:

    > var mf = new MessageFormat('en');
    > mf.currency = 'EUR';
    > var mfunc = mf.compile("The total is {V,number,currency}.");
    > mfunc({V:5.5})
    "The total is €5.50."
    

    Or by setting the formatter function directly:

    > var mf = new MessageFormat('fi');
    > var mfunc = mf.compile("Yhteensä {V,number,currency}.");
    > mf.runtime.fmt.number = MessageFormat.format.number({currency:'EUR'});
    > mfunc({V:5.5})
    "Yhteensä 5,50 €."
    

    You can also define your own functions:

    > var mf = new MessageFormat( 'en' );
    > var mfunc = mf.compile("This is {V,uppercase}.");
    > mf.runtime.fmt.uppercase = function(v) { return v.toUpperCase(); };
    > mfunc({V:"big"})
    "This is BIG."
    

    The {V,fn,...} format accepts any number of comma-delimited parameters that are passed on to fn(v,lc,p). If there's just one parameter, it's passed as a string; otherwise p is an array, or null for none.

    The default formatting functions are automatically included in mf.runtime when encountered by mf.precompile() (as seen in the first example above); additional auto-loading formatting functions may be added to MakeFormat.format.


    To make all of the above work properly, I needed to redefine mf.lc to be an array, which gets passed on to the Intl methods. This meant that the MessageFormat constructor got reworked, and now accepts a string or an array as a first locale parameter. Semantics with string input are the same as before: fallback are successive stages of dropping [-_][^-_]+ parts from its end. If locale is an array, though, it's taken to be an ordered list of locales to try, like here.

    There's also a new method MessageFormat.pluralFunc(locale) which wraps make-plural.js usage. It also tries to access root.MakePlural, which means that usage in a browser environment no longer requires manually setting MessageFormat.locale values, so this works:

    <script src="path/to/messageformat.js"></script>
    <script src="path/to/make-plural.js"></script>
    <script>
      var mf = new MessageFormat('en');
      var mfunc = mf.compile("The total is {V,number,currency}.");
      console.log(mfunc({V:5.5}));  // "The total is $5.50."
    </script>
    

    mf.runtime is also simplified a bit, getting rid of two of the utility functions and putting the formatting functions into their own namespace mf.runtime.fmt. I also renamed mf.runtime.lc to mf.runtime.pf as it holds plural functions. It's now a separate object from MessageFormat.locale, and only contains the plural functions that are explicitly included.


    Questions to consider

    • [x] Should MessageFormat() take as a third parameter an object of formatting functions?
    • [x] Should MessageFormat.format be renamed to something more specific?
    • [x] Should MessageFormat.locale also be renamed to more clearly refer to the plural functions it contains?
    • [x] Are we ok depending on Intl? Should that dependence be explicit, and/or checked at runtime?
    opened by eemeli 13
  • Add JSDoc comments to source

    Add JSDoc comments to source

    Working towards better documentation, I added JSDoc commentary throughout the source. In addition to being readable in situ, it compiles to HTML pretty cleanly.

    While at it, I cleaned up the source in a couple of places, most visibly moving mparser = require('./message_parser') to be within MessageFormat._parse, and removing the _ prefixes of the runtime functions.

    This could be left as is, or we could add jsdoc as a dependency, along with a suitable config file and a make rule. Here's the minimal conf.json I've been using so far:

    {
      "source": { "include": [ "lib/messageformat.dev.js" ] },
      "plugins": [ "plugins/markdown" ]
    }
    

    Regarding the copyright statement, I went for now with "2012-2015 Alex Sexton and other contributors". Is that all right?

    opened by eemeli 11
  • export i18n generated file as a commonJS module

    export i18n generated file as a commonJS module

    I'm working on a dust helper for mf, and because this helper needs to work server and browser-side, I need to take advantage on the i18n.js file.

    Currently (v0.1.8) precompiled functions are only exposed to the window object.

    In order to be able to take advantage of that file but server-side too, I think it could be great if we could make this file a commonJS module, with this pattern:

    var o = {};
    
    o['my/super/template'] = {
      foo: function () {...},
      bar: function () {...}
    };
    ...
    
    // CommonJS and browser exports
    this["i18n"] = this["i18n"] || o;
    if (typeof module !== "undefined" && module !== null) { // check module variable exists
      module.exports = this["i18n"];
    }
    

    Like this, browser-side we could:

    <script src="locale/en.js"></script>
    <script>
    alert(i18n['my/super/template']['foo']());
    </script>
    

    but also server-side:

    var i18n = require('./locale/en.js');
    console.log(i18n['my/super/template']['foo']());
    

    I've forked the v0.1.8 for my needs here, but could be great if you could bring that modification to your master.

    opened by abernier 11
  • Add option for array output

    Add option for array output

    Fixes #241

    This adds a new method MessageFormat#setArrayOutput(), which makes compiled functions return arrays instead of strings, allowing for variable values to not be stringified. Some examples:

    const mf = new MessageFormat('en').setArrayOutput()
    
    mf.compile('simple message')()
    // ['simple message']
    
    const obj = { foo: 'bar' }
    mf.compile('objectively, {obj} is an object')({ obj })
    // ['objectively, ', obj, ' is an object']
    
    mf.compile('select {num, plural, one{one} other{#}}')({ num: 42 })
    // ['select ', [42]]
    opened by eemeli 10
  • chore(deps): Bump json5 from 2.2.1 to 2.2.2

    chore(deps): Bump json5 from 2.2.1 to 2.2.2

    Bumps json5 from 2.2.1 to 2.2.2.

    Release notes

    Sourced from json5's releases.

    v2.2.2

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).
    Changelog

    Sourced from json5's changelog.

    v2.2.2 [code, diff]

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).
    Commits
    • 14f8cb1 2.2.2
    • 10cc7ca docs: update CHANGELOG for v2.2.2
    • 7774c10 fix: add proto to objects and arrays
    • edde30a Readme: slight tweak to intro
    • 97286f8 Improve example in readme
    • d720b4f Improve readme (e.g. explain JSON5 better!) (#291)
    • 910ce25 docs: fix spelling of Aseem
    • 2aab4dd test: require tap as t in cli tests
    • 6d42686 test: remove mocha syntax from tests
    • 4798b9d docs: update installation and usage for modules
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies javascript 
    opened by dependabot[bot] 0
  • chore(deps): Bump loader-utils from 2.0.3 to 2.0.4

    chore(deps): Bump loader-utils from 2.0.3 to 2.0.4

    Bumps loader-utils from 2.0.3 to 2.0.4.

    Release notes

    Sourced from loader-utils's releases.

    v2.0.4

    2.0.4 (2022-11-11)

    Bug Fixes

    Changelog

    Sourced from loader-utils's changelog.

    2.0.4 (2022-11-11)

    Bug Fixes

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies javascript 
    opened by dependabot[bot] 0
  • fix(compiler): Generate backwards-compatible code to not crash on old browsers

    fix(compiler): Generate backwards-compatible code to not crash on old browsers

    Since adopting @messageformat/core we've been running into various issues for some users on old browsers. For most of the issues the combination of Babel and polyfills handles it, but it appears this specific code is generating a string that contains an arrow function that's being passed to eval(), which of course Babel can't deal with. Trivial change, tested on Chrome 38 on our game (https://worlds.frvr.com, still have the old version live), mostly just had to change a bunch of test case outputs to match.

    opened by Jimbly 6
  • fix(core): Do not select plurals for non-top level compilations

    fix(core): Do not select plurals for non-top level compilations

    Fixes: https://github.com/messageformat/messageformat/issues/361

    This is a sketch to fix 361. I can see it being desirable to hide the inner recursive parameter by creating an "outer" and "inner" function, but I opted for the most simple approach.

    opened by dpchamps 0
  • bug: Potentially unexpected output given the

    bug: Potentially unexpected output given the "*" operator

    While authoring https://github.com/messageformat/messageformat/pull/360, I noticed a potentially unexpected edge case while using the * operator:

    Let's say I'm authoring some messages, and I want to be overly terse:

    const messagePacks = {
        "en": {
          es: "Estimation Date: {date, date, ::EEEMMMd}",
          fi: "Financial Incentive Date: {date, date, ::EEEMMMd}",
        },
      };
    

    If I were to compile this against the new MessageFormat("*") invocation, I'm going to get very unexpected output. Namely, spanish and finnish localized dates.

    See the repro here: https://github.com/dpchamps/mf-locale-collision-repro

    Idea for a fix: we could add an optional arg to compile to indicate isRecursing, and then not pull from the plurals at all.

    bug 
    opened by dpchamps 1
  • [email protected](Dec 11, 2022)

    messageformat v4.0.0-2

    • Drop RuntimeFunction.options; provide instead castAsBoolean() and castAsInteger() (df30cb5)
    • Simply Runtime type, dropping intermediate object as now unnecessary (43d8e40)
    • Allow MatchValue.p.matchSelectKey() to return Meta values (8403abe)
    • Minor fixes (dd39fc4)

    @messageformat/fluent v0.3.0

    • Do not flatten Fluent attributes into separate top-level messages (ceece0d)
    Source code(tar.gz)
    Source code(zip)
  • [email protected](Oct 21, 2022)

    Features

    • Add message stringifier (701fceb)
    • Accept MessageFormat instance as stringifyMessage() arg (b7cf093)
    • Normalise markup handling (3bdaace)
    • Local variables cannot refer to later definitions (unicode-org/message-format-wg#305, 7ae83a5)

    Bug Fixes

    • Add type guard isCatchallKey(); export isText() (cd06de8)
    • Drop {} wrappers from markup-start and markup-end sources (6d903b0)
    • Prefer local over external variables (5b09cfe)
    Source code(tar.gz)
    Source code(zip)
  • [email protected](Jul 16, 2022)

    This is the first prerelease version of messageformat as a polyfill for the Intl.MessageFormat proposal, along with with its @messsageformat/icu-messageformat-1 and @messageformat/fluent compatibility packages. This proposal is built on top of the developing Unicode MessageFormat 2.0 specification, "MF2".

    Going forward, the intent is to track the TC39 proposal and to provide both a performant polyfill for it, as well as tooling for editors and other users of MF2. The ICU MessageFormat ("MF1") packages will still be maintained, but are unlikely to experience much new feature development.

    What's Changed

    • cli and rollup-plugin: Major version updates to account for requiring Node.js v14 or later due to dependency updates by @eemeli
    • docs(guide): Update link for DateFormat skeleton string by @floratmin in https://github.com/messageformat/messageformat/pull/367
    • feat(number-skeleton): Add rounding-modes Half Ceiling and Half Floor by @floratmin in https://github.com/messageformat/messageformat/pull/370

    Full Changelog: https://github.com/messageformat/messageformat/compare/@messageformat/[email protected]@4.0.0-0

    Source code(tar.gz)
    Source code(zip)
  • @messageformat/[email protected](Feb 6, 2022)

    New packages versions:

    • @messageformat/cli v3.1.0
    • @messageformat/core v3.0.1
    • @messageformat/runtime v3.0.1

    Features

    • cli: Support JSON5 (#345)

    Bug Fixes

    • cli: Always include both / and \ in delimiters (#343)
    • cli: Do not drop initial keys for single-message input files (#340)
    • core: Relax MessageFunction argument type (#351)
    • runtime: Use a string type in the select() arguments (#344)
    • runtime: Add missing messages.d.ts (#342)
    Source code(tar.gz)
    Source code(zip)
  • @messageformat/[email protected](May 13, 2021)

    The changes below are in addition to the changes introduced in 3.0.0-beta.1 and 3.0.0-beta.2.

    BREAKING CHANGES

    • Tests for the library in Node.js 10 are dropped. No immediate changes should cause any part of the library not to work with Node.js 10, but that will no longer be verified by CI tests or otherwise. (#322)

    Features

    • core: Use fat-arrow notation for message functions (#309)
    • core: Rename "strictNumberSign" option as "strict" ([#311)
    • Use TS generics to specify the message function return type (#312)
    • core: Allow for custom formatters imported from runtime modules (#313)
    • core: Make arg shape customisable for custom formatters (#313)

    Bug Fixes

    • react: Minor docs & typing tweaks for tooling compatibility (#296)
    • runtime: Add missing esm/package.json (#308)
    • Tighten up TS types, getting rid of almost all any (#312)
    • core: Allow overriding default formatters (#313)
    • core: Properly complain about reserved identifier names during build (#313)
    • react: Expand pathSep typing (#319)
    Source code(tar.gz)
    Source code(zip)
  • [email protected](Jul 23, 2020)

    Features

    • Add support for number patterns & skeletons (#272)
    • Add support for date skeletons (#279)
    • compiler: Add requireAllArguments option to compiler (#267)
    • build: Replace Webpack with Rollup as messageformat bundler (#278)

    Bug Fixes

    • Update make-plural dependency to 6.0.1
    Source code(tar.gz)
    Source code(zip)
  • [email protected](Jul 23, 2020)

    BREAKING CHANGES

    messageformat/compile-module

    • Split compileModule() from compile(). This refactors a core API, separating the compilation of individual messages vs. collections of messages.

    • Output module string directly from compileModule(). Before, compiled modules could be directly used, and included a built-in stringifier. Now, compiled modules are output as the source code of an ES module.

    • Make compileModule() into a separate function. The module compiler now needs to be imported separately when used.

      Before:

      import MessageFormat from 'messageformat'
      const mf = new MessageFormat('en')
      mf.compile(...)
      

      Now:

      import MessageFormat from 'messageformat'
      import compileModule from 'messageformat/compile-module'
      const mf = new MessageFormat('en')
      compileModule(mf, ...)
      

    messageformat-runtime

    • Move runtime to its package; split stringify-dependencies from it
    • Add runtime dependency on messageformat-runtime
    • Add runtime dependency on make-plural@6. This change introduces import statements into the module output.
    • Merge formatters into runtime. This drops/deprecates the messageformat-formatters package, moving its exports to messageformat-runtime/lib/formatters.
    • Merge messages into runtime. Previously, messages were a part of the core messageformat package. To use them, messageformat needed to be installed as a runtime rather than dev dependency.
    • Stop reusing runtime. This removes the MessageFormat#runtime instance
    • runtime: Refactor, dropping class wrapper. This drops the error-throwing from the non-strict number() variant.

    Options

    • Drop MessageFormat#addFormatters(). Use the customFormatters constructor option instead.

    • Drop MessageFormat#setBiDiSupport() & #setStrictNumberSign(). Use the biDiSupport & strictNumberSign constructor options instead.

    • Use the options object to set the default currency. This changes the API

      Before:

      import MessageFormat from 'messageformat'
      const mf = new MessageFormat('en')
      mf.currency = 'EUR'
      const msg = mf.compile('{V, number, currency}')
      

      Now:

      import MessageFormat from 'messageformat'
      const mf = new MessageFormat('en', { currency: 'EUR' })
      const msg = mf.compile('{V, number, currency}')
      

    Other Breaking Changes

    • Refactor plurals, and a few other things. This drops the second locale arg of MessageFormat#compile(), and removes the default of supporting all locales if initialised with an empty locale. Also, the API for custom plural categorisation functions now expects an array rather than an object of functions.
    • Always format # as number. Previously, non-numeric values used as plural arguments could be referred to using # while keeping their original value. With this change, they now get converted to numbers and then formatted, probably coming out as "NaN" instead.
    • Refactor formatter caching during compilation. This drops MessageFormat.formatters as well as MessageFormat#fmt, which had public visibility but were not explicitly documented as public.
    • Always apply locale-specific checks to plural cases. This removes both the pluralKeyChecks option, as well as the disablePluralKeyChecks() method. To avoid the checks, pass in your own plural category function.

    Features

    • Add choice between string & values array output (#242)
    • Add special-casing for common number formatters
    • Add special locale "*" to match all of them
    • Use cardinal-only plurals where appropriate
    • Add static supportedLocalesOf() method
    • Import formatters in runtime
    • Move getFormatter() to compiler.js
    • Publish identifier utils as safe-identifier
    • Refactor compiler output
    • Refactor/clean up compile() internals

    Bug Fixes

    • Adjust for formatter API change
    • Support selectordinal with offset
    • runtime: Cache Intl.NumberFormat instances for #
    Source code(tar.gz)
    Source code(zip)
  • [email protected](Jul 23, 2020)

    Features

    • Add customFormatters to constructor options
    • Add internal options object
    • Add options as second constructor argument
    • Update index.d.ts

    Bug Fixes

    • Update dependencies
    Source code(tar.gz)
    Source code(zip)
  • [email protected](Jul 23, 2020)

    Features

    • formatters: Split into its own package from messageformat
    • Drop dependency on reserved-words, inlining data
    • Move sources to src/, use Babel as transpiler targeting Node 6.5
    • Refactor compiler.js as ES6, splitting out utils.js
    • Refactor messageformat.js as ES6
    • Refactor plurals.js as ES6
    • Refactor runtime.js as ES6
    • Replace Browserify + UglifyJS with Webpack as build tool

    Bug Fixes

    • Build Web export from src with babel-loader, configured with browser targets
    • Refactor/fix UMD/CommonJS exports
    Source code(tar.gz)
    Source code(zip)
  • [email protected](Jul 23, 2020)

    • Harmonise code style with Prettier & add linting with ESLint (#220)
    • compiler: Allow MessageFormat content in function parameters
    • messageformat: Update messageformat-parser to 4.0
    • Refactor as a monorepo, using Lerna (#212)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.5(Dec 15, 2018)

    • Support BCP47 tag resolution for new MessageFormat().compile(src, "fr-FR") (#197)
    • messageformat-cli v2.0.3:
      • Automatically detect UTF-8/Latin-1 encoding for .properties files (#206 by @skress)
    • TS definitions:
      • Define toString with optional global argument (#208 by @rbardini)
      • Use type union parameter for MessageFormat constructor (#210 by @lephyrus)
    • Fix guide.md typo (#211 by @Kemito)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.4(Jul 21, 2018)

  • v2.0.3(Jul 19, 2018)

  • v2.0.2(Apr 23, 2018)

  • v2.0.1(Apr 18, 2018)

    • Add TypeScript definition file (#194)
    • Force input to string in MessageFormat.escape
    • cli: Fix prepare script (install was failing on 2.0.0)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Apr 4, 2018)

    Breaking Changes

    • Publish the messageformat CLI binary as its own package messageformat-cli
      • Support reading locale data from .properties files
      • Read config from package.json and messageformat.rc.json
      • Add new options --delimiters, --eslint-disable, --extensions, --outfile, and --simplify
    • Update messageformat-parser from 1.1.0 to 3.0.0
      • To conform with the ICU MessageFormat standard, escaping with a \ is no longer supported. Instead, use 'quotes' to escape {} and # when needed. To help deal with this change, we provide a codemod to handle the change for you.
      • The optional parameter passed to a formatter function is now a string, rather than an array of strings. So with e.g. {var, func, your param}, the parameter passed to func would be 'your param'.
      • Closer conformance with the spec for identifiers, which means that characters in [:Pattern_Syntax:] are no longer allowed in identifiers. Note in particular that this includes -, which was previously allowed.
    • Expect Intl to exist and drop #setIntlSupport()
    • Compiled output:
      • Default to ES6 module output from #toString() with no parameters
      • Drop support for #toString('exports'); use #toString('module.exports') for CommonJS output

    Other Changes

    • Rename the repository as messageformat/messageformat, dropping the final .js
    • Completely revamp the website
    • Add a runtime accessor class Messages, available as import Messages from 'messageformat/messages'
    • Refactor formatters
      • Add duration formatter
      • number: add currency:CODE option
    • Use npm scripts rather than Makefile to test and build the package
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.5(Mar 28, 2018)

  • v2.0.0-beta.4(Mar 28, 2018)

    • Breaking change: Drop support for #compile().toString('exports')
    • Add runtime accessor class (#189)
    • Refactor formatters to lib/formatters/
      • Add duration
      • number: Refactor, adding currency:CODE option
      • Expand docs & add tests
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.2(Mar 28, 2018)

    messageformat-cli v2.0.0-beta.3

    • Add --delimiters, --extensions, and --outfile
    • Read config from package.json and messageformat.rc.json
    • Add support for .properties files

    messageformat-parser v3.0.0-beta.2

    • Breaking change: Drop all \ escapes (#171, messageformat/parser#7)
    • Breaking change: Replace function params with single param, drop strictFunctionParams option (#185, messageformat/parser#1)
    • Add codemod for v1/2 -> v3 deprecations
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.1(Mar 28, 2018)

    Breaking Changes

    • Expect Intl to exist, drop #setIntlSupport (#173)
    • Update messageformat-parser to 2.0.0
      • Closer conformance with the ICU MessageFormat spec with respect to quoting and escaping text (messageformat/parser#3) and whitespace (messageformat/parser#6), thanks to @nkovacs.
    • Split messageformat-cli into its own package on npm
      • mv bin/ cli/
      • Add --es6, --eslint-disable, --simplify
    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Mar 28, 2018)

  • v1.1.0(Nov 18, 2017)

    • Update JS Foundation info & CLA
    • bin/messageformat: Add --enable-intl-support (thanks @hey99xx)
    • Readme updates (thanks @amilajack)
    • Update Travis CI config: Drop v0.10, v0.12 & iojs, add v4 & v6
    • Don't require other in plurals when plural functions have been set manually
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Sep 26, 2016)

    • Add MessageFormat.escape (see #160)
    • Fix #161 - Intl polyfill requires new Intl.NumberFormat()
    • Drop node 0.8 from Travis CI tests -- tests pass, but JSDoc generation fails (part of npm run prepublish)

    (1.0.1 was missing the compiled files, hence the re-release)

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Sep 14, 2016)

  • v0.3.1(Feb 20, 2016)

    • IE8 bugfix: Special handling for ES3 reserved words (PR #122)
    • Improve multi-instance/multi-language support (Issue #134)
    • Improve code documentation, esp. examples
    • Update authors
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Jan 30, 2016)

human friendly i18n for javascript (node.js + browser)

BabelFish - human friendly i18n for JS Internationalisation with easy syntax for node.js and browser. Classic solutions use multiple phrases for plura

Nodeca 246 Nov 20, 2022
Gettext Style i18n for Modern JavaScript Apps

Jed Gettext Style i18n for Modern JavaScript Apps For more info

null 879 Dec 14, 2022
Extract and merge i18n xliff translation files for angular projects.

Angular extract i18n and merge This extends Angular CLI to improve the i18n extraction and merge workflow. New/removed translations are added/removed

Daniel Schreiber 86 Jan 5, 2023
Internationalization for react done right. Using the i18next i18n ecosystem.

react-i18next IMPORTANT: Master Branch is the new v10 using hooks. $ v10.0.0 npm i react-i18next react-native: To use hooks within react-native, you m

i18next 7.9k Dec 30, 2022
Merges XLIFF 1.2/2.0 files. Usable for Angular i18n automation.

XLIFF Simple Merge This program automates the merging of XLIFF files (version 1.2 and 2.0). New translations from the input file (e.g. "messages.xlf")

Daniel Schreiber 9 Dec 15, 2022
The alternative internationalization (i18n) library for Angular

NGX Locutus The alternative Angular Translation Library used for large scale microfrontend translations. No more worrying about shared translation ass

Stefan Haas 9 May 31, 2022
Type-safe internationalization (i18n) for Next.js

Type-safe internationalization (i18n) for Next.js Features Usage Examples Scoped translations Change current locale Use JSON files instead of TS for l

Tom Lienard 251 Dec 22, 2022
🌍📖 A readable, automated, and optimized (5 kb) internationalization for JavaScript

Linguijs ?? ?? A readable, automated, and optimized (5 kb) internationalization for JavaScript Documentation · Documentation 2.x · Quickstart · Exampl

Lingui 3.5k Jan 2, 2023
Give your JavaScript the ability to speak many languages.

Polyglot.js Polyglot.js is a tiny I18n helper library written in JavaScript, made to work both in the browser and in CommonJS environments (Node). It

Airbnb 3.6k Jan 2, 2023
:orange_book: simple approach for javascript localization

ttag ⚠️ This project was previously named c-3po. Some of the talks, presentations, and documentation may reference it with both names. Modern javascri

ttag 307 Jan 2, 2023
lightweight jQuery plugin for providing internationalization to javascript from ‘.properties’ files

jQuery.i18n.properties About jQuery.i18n.properties is a lightweight jQuery plugin for providing internationalization to javascript from ‘.properties’

null 408 Dec 25, 2022
A JavaScript Internationalization Framework

FBT is an internationalization framework for JavaScript designed to be not just powerful and flexible, but also simple and intuitive. It helps with th

Facebook 3.8k Jan 8, 2023
Powerful, intelligent and easy to use Figma internationalisation scripts

Powerful, intelligent and easy to use Figma internationalisation scripts English | 中文 ?? Script Installation Before installing the Figma I18n script,

Afeyer 138 Dec 10, 2022
ICU MessageFormat for Javascript - i18n Plural and Gender Capable Messages

messageformat The experience and subtlety of your program's text can be important. Messageformat is a mechanism for handling both pluralization and ge

null 1.6k Dec 23, 2022
Formats message strings with number, date, plural, and select placeholders to create localized messages

Formats message strings with number, date, plural, and select placeholders to create localized messages. Small. Between 700 bytes and 1.3 kilobytes (m

Marcis Bergmanis 35 Oct 30, 2022
i18n-language.js is Simple i18n language with Vanilla Javascript

i18n-language.js i18n-language.js is Simple i18n language with Vanilla Javascript Write by Hyun SHIN Demo Page: http://i18n-language.s3-website.ap-nor

Shin Hyun 21 Jul 12, 2022
This server is made to serve the MSN-Messenger app develop by Gabriel Godoy. This applications is capable to register users and messages in order implements a real time chat.

?? MSN-Messenger-Server Node.js server for real time chat About | Installations | How to Use | Documentation | Technologies | License ?? About This se

Guilherme Feitosa 7 Dec 20, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Qwerty is the first social website focused on connecting students with similar classes and gender identities

?? Qwerty ?? Qwerty is the first social website focused on connecting students with similar classes and gender identities. To get started simply input

Benson Liu 3 Oct 21, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022