Git Product home page Git Product logo

formatjs's Introduction

formatjs's People

Contributors

akx avatar apipkin avatar bertho-zero avatar brichardssa avatar caridy avatar cungminh2710 avatar dependabot-preview[bot] avatar dependabot[bot] avatar drewfish avatar ericf avatar gamtiq avatar greenkeeperio-bot avatar ilteoood avatar inukshuk avatar jasonmit avatar juandopazo avatar leoyli avatar longlho avatar marcesengel avatar okuryu avatar pkuczynski avatar psalv avatar pyrocat101 avatar redonkulus avatar renovate[bot] avatar roderickhsiao avatar santialbo avatar skoging avatar swernerx avatar ykzts avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

formatjs's Issues

Pipe Intl `messages` through context, like `locales` and `formats`

The examples given in the README (See note in #7) have messages hardcoded into the React components. In reality, this would be a bad practice, and it would generally be useful to be able to access the same messages in multiple components.

I think we should also pipe messages through the component context, like we do for locales and formats.

custom component 'wrappers'

another thing i think would be useful is to be able to wrap react-intl components in our own components

i see there already is support for string tags, but that limits us to html only.
say i have a Textcomponent, i'd like to do

<ReactIntl.FormattedMessage
  message="yizeerr"
  component={require('components/Text')}
/>

i tried it out quickly yesterday and it worked, so it should be quite easy to implement. i could submit a pull request soon if you're okay with that.

one thing i still don't know is how to properly 'propType' that component.
i suppose with react 0.13 we could have something like React.PropTypes.instanceOf(React.Component)

i've only needed that for FormattedMessage so far but it could be useful for the other components

Browserify/requiring react-intl in IE8 breaks

Awesome library! I've been using browserify and requiring modules as needed, which was working well until I decided to mess around in IE8. It seems that the react-intl module (and its integrations: intl-relativeformat, intl-messageformat, intl-messageformat-parser, and intl-format-cache) make use of default (e.g. index.js: require('./lib/main'/).default), a keyword in IE. Would it be possible to change instances of key-value access via .default to ['default']?

In the meantime I've moved all my react dependencies into script tags in the HTML page, along with react-intl. It'd be nice to be able to manage them all via browserify again though!

Error when loading via requirejs

The example works fine when loading via a script tag, but when trying to move this over to load via requirejs there is an error:
Line 98: Uncaught type error: undefined is not a function
It appears to be trying to call methods on MessageFormat (this._mergeFormats) which don't exist yet.

Here is a stripped down example which shows the error:

<body>
    <div id="content">
    </div>

    <script src="../requirejs/require.js"></script>

    <script>
        require.config({
            baseUrl: '',
            paths: {
                "react": "../react/react",
                "react-intl": "../react-intl/dist/react-intl"
            }
        });

        require(['react', 'react-intl'], function (React, ReactIntlMixin) {

        });

    </script>
</body>

Should this be able to load via require as-is or is there something else I am missing?

Splitting messages into smaller chunks

Similarly as with the dojo toolkit i18n I'd like to split components messages into single files.

  • It would help developers to care about their own components and localizations.
  • Translators would also receive smaller, organized files.
  • A build script could easily identify the missing messages.
  • A language could be chosen a fallback for missing translations (only for brave people :-).

For example having two components, <Alien/> and <Earthling/>, a directory structure would be:

└── components
    ├── Earthling.jsx
    ├── Alien.jsx
    └── nls
        ├── en
        │   ├── Earthling.js
        │   └── Alien.js
        ├── es
        │   ├── Earthling.js
        │   └── Alien.js
        └── it
            ├── Earthling.js
            └── Alien.js
// nls/en/Earthling.js
{
    'greetings': 'Hello, Earth!'
}
// nls/en/Alien.js
{
    'greetings': 'Hello, Saturn!'
}

In a dev or a server-side environment, the components would require the localized module from the proper nls folder, using it as default prop.messages for the IntlMixin (not clear yet how, maybe with a static method?).

On the client, only in production, the components should instead consume a unique, big module for each language – that needs to be available before rendering the app. A build script, e.g. webpack, would recognize the requires pointing to a nls folder and produce such files, for example:

// built en.js
{ 
  messages: {
    'Earthling': {
        'greetings': 'Hello, Earth!',
    },
    'Alien': {
        'greetings': 'Hello, Saturn!'
    }
 }
}
// built es.js
{ 
  messages: {
    'Earthling': {
        'greetings': '¡Hola, Tierra!',
    },
    'Alien': {
        'greetings': '¡Hola, Saturno!'
    }
 }
}
// built it.js
{ 
  messages: {
    'Earthling': {
        'greetings': 'Ciao, Terra!',
    },
    'Alien': {
        'greetings': 'Ciao, Saturno!'
    }
 }
}

Clearly this need to change the way the component is getting the message: this.getIntlMessage('greetings') vs. this.getIntlMessage('Earthling.greetings') (in the compiled version).

I'd like to know how do other developers deal with the problem? Is this something react-intl should help us to achieve? Or I am overcomplicating the solution? :0

Strategies for using JSX in messages?

I've run into a few cases where my messages need inline JSX (like a link or presentational markup). I'm handling that now by chopping messages up around the JSX, but it's a bummer to lose the overall translation context. I'm curious if you have employed any other approaches to handle this situation?

Number/Date/Mixin components exposed as IntlNumber/IntlDate/IntlMixin

This is a feature request to export the Number/Date/Mixin components as IntlNumber/IntlDate/Mixin.

I love using the ES6 object destructuring syntax, but when I'm consuming react-intl components I cannot use it because it would "hide" the built in Number/Date types. Mixin is slightly different in that there is no conflict -- I just always rename it to IntlMixin to make it a bit more clear about it's use.

I'd love to be able to do the following.

var { IntlNumber, IntlDate, IntlMixin } = require('react-intl');

Instead of

var ReactIntl = require('react-intl'),
  IntlNumber = ReactIntl.Number,
  IntlDate = ReactIntl.Date,
  IntlMixin = ReactIntl.Mixin;

And if you end up going this route, I'd probably prefix the other ones with Intl for consistency.

Formate date with one part

Hey, is there any way to only return part of a date using this.formatDate, e.g. only the month or weekday?

I’ve tried creating a custom format and passing the options directly like { month: 'long' }. Unfortunately both didn’t work. The only way I see right now is using the Intl polyfill directly, like date.toLocaleString(locale, { month: "long" }).

Provide option to ignore unfound message exceptions.

In development it often makes sense to create a message key to be processed later. E.g. given when message files are auto generated or provided by a different process you can't control. In such a case, you don't want everything to grind to a halt just because a message key is not there.

I suggest adding an option, similar to what I use developing against similar APIs in Java to ignore unfound messages. If turned on, simply the message key itself should be printed in case the item is not found

Superfluous line in the file localization?

Hello!
Localization files for each locale contains method pluralRuleFunction
For example:

pluralRuleFunction: function (n) {
        var i = Math.floor(Math.abs(n)), v = n.toString().replace(/^[^.]*\.?/, "").length;
        n = Math.floor(n);
        if (i === 1 && v === 0)return "one";
        return "other";
    }

What for n = Math.floor(n) ?

Accept keys with period (".")

Currently, getIntlMessage only accepts a path. So passing in foo.bar would look up data where foo is a parent of bar.

There should be a way to allow keys with a period character where passing in foo.bar would get foo.bar key in the messages object instead of getting foo and getting bar within foo

Question: example that shows conditional loading of Intl.js

Hi,

The examples provided don't offer sufficient support to get started without questions. It just gives you enough information to almost understand how to set it up in a real world scenario, but not quite. And struggles follow.

I find myself with the following questions

  • I'm looking for an example that shows the conditional loading of Intl.js both in the browser and in node.js. This, in the context of creating a distribution.js for my application with gulp. I want to avoid including Intl.js there in the distribution when during packaging Intl.js will obviously not be there.
  • Can I specify a normal properties style text file as a source for messages?
  • I work w global message files (as opposed to component level message files). What's the best way to only load the correct one? I can load based on the applied locale, but if that's not available it should revert back to the default and load only that.
  • The library seems to use either props or context to reference a message bundle. How do I work with a globally available language file in order not to have to pass this through each and every time.
  • is it possible to set the library up so that any message that is not found will just return the provided message key? In a dev scenario, you may not want to have to supply all the correct messages up front. and imho a non-available messages file should not result follow this scenario and provide a warning in stead of throwing an exception.

My suggestion: provide a small complete scenario that is set up for production and development.

Links and other tags in messages

How would you deal with messages containing tags, e.g. links?

For example this can't be rendered by React:

const message = 'Visit <a href="https://github.com">github</a> now!';

A solution is that in use by khan academy. Then I would write something like:

const messages = { visit: 'Visit %(link)s now!', link: 'github' }
<p>
  <$_ link={ <a href="https://github.com">this.getIntlMessage('link')</a> }>
       { this.getIntlMessage('visit') }
  </$_>
</p>

I wonder how are other developers solving this case? Could react-intl help with it?

Tripple webpack injection

Hello!
For now I see that in result webpack bundle I have 3 repetitive modules react-intl/lib/main.js
Moreover, each of it requires their own react-intl/lib/en.js

/* 475 */
/***/ function(module, exports, __webpack_require__) {
    "use strict";
    exports["default"] = {"locale":"en","pluralRuleFunction":function (n) {var i=Math.floor(Math.abs(n)),v=n.toString().replace(/^[^.]*\.?/,"").length;n=Math.floor(n);if(i===1&&v===0)return"one";return"other";},"fields":{"second":{"displayName":"Second","relative":{"0":"now"},"relativeTime":{"future":{"one":"in {0} second","other":"in {0} seconds"},"past":{"one":"{0} second ago","other":"{0} seconds ago"}}},"minute":{"displayName":"Minute","relativeTime":{"future":{"one":"in {0} minute","other":"in {0} minutes"},"past":{"one":"{0} minute ago","other":"{0} minutes ago"}}},"hour":{"displayName":"Hour","relativeTime":{"future":{"one":"in {0} hour","other":"in {0} hours"},"past":{"one":"{0} hour ago","other":"{0} hours ago"}}},"day":{"displayName":"Day","relative":{"0":"today","1":"tomorrow","-1":"yesterday"},"relativeTime":{"future":{"one":"in {0} day","other":"in {0} days"},"past":{"one":"{0} day ago","other":"{0} days ago"}}},"month":{"displayName":"Month","relative":{"0":"this month","1":"next month","-1":"last month"},"relativeTime":{"future":{"one":"in {0} month","other":"in {0} months"},"past":{"one":"{0} month ago","other":"{0} months ago"}}},"year":{"displayName":"Year","relative":{"0":"this year","1":"next year","-1":"last year"},"relativeTime":{"future":{"one":"in {0} year","other":"in {0} years"},"past":{"one":"{0} year ago","other":"{0} years ago"}}}}};

    //# sourceMappingURL=en.js.map

/***/ },
/* 476 */
/***/ function(module, exports, __webpack_require__) {
    "use strict";
    var src$mixin$$ = __webpack_require__(477), src$en$$ = __webpack_require__(475);

    src$mixin$$.default.__addLocaleData(src$en$$.default);

    exports["default"] = src$mixin$$.default;

    //# sourceMappingURL=main.js.map

/***/ },

/* 483 */
/***/ function(module, exports, __webpack_require__) {
    "use strict";
    exports["default"] = {"locale":"en","pluralRuleFunction":function (n) {var i=Math.floor(Math.abs(n)),v=n.toString().replace(/^[^.]*\.?/,"").length;n=Math.floor(n);if(i===1&&v===0)return"one";return"other";}};

    //# sourceMappingURL=en.js.map

/***/ },
/* 485 */
/***/ function(module, exports, __webpack_require__) {
    "use strict";
    var src$core$$ = __webpack_require__(482), src$en$$ = __webpack_require__(483);

    src$core$$.default.__addLocaleData(src$en$$.default);
    src$core$$.default.defaultLocale = 'en';

    exports["default"] = src$core$$.default;

    //# sourceMappingURL=main.js.map

/***/ }

/* 491 */
/***/ function(module, exports, __webpack_require__) {
    "use strict";
    exports["default"] = {"locale":"en","pluralRuleFunction":function (n) {var i=Math.floor(Math.abs(n)),v=n.toString().replace(/^[^.]*\.?/,"").length;n=Math.floor(n);if(i===1&&v===0)return"one";return"other";},"fields":{"second":{"displayName":"Second","relative":{"0":"now"},"relativeTime":{"future":{"one":"in {0} second","other":"in {0} seconds"},"past":{"one":"{0} second ago","other":"{0} seconds ago"}}},"minute":{"displayName":"Minute","relativeTime":{"future":{"one":"in {0} minute","other":"in {0} minutes"},"past":{"one":"{0} minute ago","other":"{0} minutes ago"}}},"hour":{"displayName":"Hour","relativeTime":{"future":{"one":"in {0} hour","other":"in {0} hours"},"past":{"one":"{0} hour ago","other":"{0} hours ago"}}},"day":{"displayName":"Day","relative":{"0":"today","1":"tomorrow","-1":"yesterday"},"relativeTime":{"future":{"one":"in {0} day","other":"in {0} days"},"past":{"one":"{0} day ago","other":"{0} days ago"}}},"month":{"displayName":"Month","relative":{"0":"this month","1":"next month","-1":"last month"},"relativeTime":{"future":{"one":"in {0} month","other":"in {0} months"},"past":{"one":"{0} month ago","other":"{0} months ago"}}},"year":{"displayName":"Year","relative":{"0":"this year","1":"next year","-1":"last year"},"relativeTime":{"future":{"one":"in {0} year","other":"in {0} years"},"past":{"one":"{0} year ago","other":"{0} years ago"}}}}};

    //# sourceMappingURL=en.js.map

/***/ },
/* 493 */
/***/ function(module, exports, __webpack_require__) {
    "use strict";
    var src$core$$ = __webpack_require__(489), src$en$$ = __webpack_require__(491);

    src$core$$.default.__addLocaleData(src$en$$.default);
    src$core$$.default.defaultLocale = 'en';

    exports["default"] = src$core$$.default;

    //# sourceMappingURL=main.js.map

/***/ }

Differences between polyfill and native Intl cause problems in isomorphic apps

I'm working on an isomorphic app and I get different outputs for a component rendered server-side and then mounted on the browser, i.e. Chrome. This causes React to warn about invalid checksum when rendering on browser and invalidate the server-rendering :(

In particular, the EUR currency format is different in Chrome (€100) and in node (€100.00). This does not happen in Safari since it also uses the same node polyfill and it outputs €100.00 as well.

Using react-intl with browserify

The react-intl node js module does a:

require('./lib/locales');

Which includes all locales by default on the module.

When bundling with browserify all the locale data is included on the bundle, which makes the bundle huge.

I think the standard way to fix it is to provide a different entry point for the browser on the packages.json, like:

"browser" : "browser.js"

and in browser.js have the same content that in index.js but without the require('./lib/locales').

There are similar issues for intl-relativeformat & intl-messageformat modules.

Would such a fix be ok?

Date format problems when using Intl.js polyfill

Very sorry to open this here since it's not directly related to react-intl but since you guys have probably already encountered this in your use at scale I figured I would bring it up here.

Everything seems to be working fine for browsers that support Intl.js natively -- but there are a few differences when using the polyfill that I was wondering how you have overcome.

  1. No support for timezone formatting except UTC -- the polyfill will throw an error if you try to supply a timezone that isn't 'UTC'
  2. Differences in date formatting -- specifically this one: andyearnshaw/Intl.js#68

Do you have products that use the Intl.js polyfill version with date or timezone formatting -- and if so, how do you get around this issue?

Also, is there a newsgroup or IRC something where I could ask questions like this instead of polluting the github issue tracker?

Thanks!

How to implement shouldComponentUpdate when using ReactIntl

I'm not clear on how a component that uses ReactIntl.Mixin (or any of the new components) can implement shoulComponentUpdate. Am I able to get at the messages/locale/formats properties from inside a subcomponent of my app so that when I switch languages I can re-render the components that use these? When using PureRenderMixin it just never re-renders the components that use it at all.

Is this just a fundamental problem when passing down the locale props down with context or is there a way to solve it?

Conflicting information on pre-defined date formats

According to formatjs.io/guide, formatjs comes with 4 pre-defined date formats:

screen shot 2014-11-24 at 1 58 00 pm

However, the React integration docs eventually make it clear (although this escaped my notice), and my experience agrees, that it doesn’t actually ship with these pre-defined.

react makes you define date formats

Please either include these 4 useful pre-defined formats in react-intl, or update the main /guide to alleviate this confusion.

Source maps

Source map URLs are included in the source from NPM but I'm not sure the actual .map files are included (i.e. lib/components/date.js includes //# sourceMappingURL=date.js.map).

As a result I get the following when using react-intl (in Safari):

Failed to load resource: The requested URL was not found on this server. (referring to date.js.map)

Change method names to format*?

Should we change the method names from intlDate(), intlNumber(), intlMessage(), etc. to: formatDate(), formatNumber(), formatMessage(), etc.?

Examples of fallbacks?

There is mention of support for providing fallbacks -- locales: ['fr-FR', 'en'], but I'm not at all clear on how you'd actually use it.

In the one example you show of using multiple languages for messages, you're explicitly passing in messages['en-US'] to the root component messages prop, so I don't see how you could ever have fallback logic when you're explicitly not passing in the messages of the other locales.

Consider Exposing React Components as an Alternate API

It would be cool to have format.js React components instead of the mixin. Something like:

return <div><Number style="percent">{0.9}</Number></div>

That way you don't need the mixin in your component.

Currently this requires an extra wrapper element, but I think we'll be able to get rid of that limitation in React.

Use <time> in place of <span> for FormattedDate, FormattedRelative, and FormattedTime?

I would like to suggested replacing

return React.DOM.span(null, this.formatDate(value, options));

with

return React.DOM.time({dateTime: value}, this.formatDate(value, options));

in the render method of FormattedRelative and similarly FormattedRelative & FormattedTime

React.DOM supports both the time element and its datetime attribute.

If you are in agreement I would love to submit a PR

Move react to peerDependencies

I'm using react with browserify and had some problems today with this nasty bug

Uncaught TypeError: Cannot read property 'firstChild' of undefined
//react-router//react/lib/ReactMount.js?:606

Luckily I found the solution at StackOverflow.

For example, if you npm install a package that requires a different React version and puts it into dependencies instead of peerDependencies, it might install a separate React into node_modules//node_modules/react.
Two different Reacts won't play nicely together (at least yet).

I removed ./node_modules/react-intl/node_modules/react and now everything works fine again.

Please update your package.json and move react to peerDependencies.

Exclude locales for webpack/browserify bundle

Hello!
I use react-intl in isomorphic application written in nodejs (i.e. commonjs) and builded for client with webpack.
But "in Node.js, the data for all locales is pre-loaded", so client bundle became extra fat. Is it possible to require only one locale?

Number formatting is inconsistent with the locale de-ch

For some weird reason the number formatting in 'de-ch' with react-intl isn't correct and isn't consistent with Intl.NumberFormat.

In this example:

var Intl = require('intl');
var ReactIntlMixin = require('react-intl');

var locale = 'de-ch';

var App = React.createClass({
  mixins: [ReactIntlMixin],
  render: function() {
    return <div>
      <p>{ this.formatNumber(103423423, { style: 'decimal' }) }</p>
    </div>;
  }
});

React.renderComponent(<App locales={[locale]} />, document.body);

The output is 103.423.423

whereas console.log(new Intl.NumberFormat([locale], {style:'decimal'}).format(103423423));

produces 103'423'423 that is what it should be.

Pass through style and className props to components

i often find myself needing to style (via style or className props) react-intl components
i see none of your components use the style or className props so far so i could submit a pull request to support that if you're fine with it.

Update README to reflect changes from Refactor

…also state the best practices for messages. We should change the example with getMyMessage(), because it hard codes a locale-specific string into the React component. Ideally, all such message strings would be externalized from the React components.

Performance with long lists?

I was doing a comparison of Angular and React and decided to try out a performance test with a long list of events and prices.

I was expecting React to beat the pants off of Angular, but suprisingly, React was taking almost 2s to render the list.

I distilled my test case to a simple rendering of numbers with currency formats and found that adding a formatNumber call in my list item increased the list render time from 10ms to 200ms -- and this is on a relatively fast computer!

https://github.com/pselden/react-render-test

Is there anything I can do to improve performance here?

I haven't distilled my angular example down to a simple test case, but even with my full prototype it was rendering locale changes in about 100ms (vs the 2seconds that it took in my full React example).

Is the Mixin format judicious?

Hello,

Just some thoughts,
Is there any added value in making this a react mixin?

  • It seems it doesn't depend on any react features and doesn't particularly fit the 'component' concern. I have yet to find a good use case for mixins, but if there was one I would imagine it closely related to rendering/lifecycle.
  • Why not favor composition over inheritance (mixin)? Once imported, you would write intl.date instead of this.intlDate. Mixing many different concerns into one component also pollutes the dynamic this pointer which is known to be annoying (React bind it only for the top level functions of a component). With composition, the lib is no longer coupled to React components, and can be called from other places.

Cheers

Currency dropping trailing zero in decimal

With a message like this:

sampleMessage: '<strong>{amount, number, usd}</strong> was charged to your credit card.'

with a custom format like so:

number: { usd: { style: 'currency', currency: 'USD' } }

and the component displaying the message with:

<div dangerouslySetInnerHTML={{__html: this.formatMessage(this.getIntlMessage('Messages.sampleMessage'), { amount:35.50, }) }} />

The currency is displaying as $35.5. This did not seem to be resolved in the last push. Is this something we're doing on our end incorrectly?

Best approach to express duration?

Lets say I want to return time taken by walking from point A to point B in minutes

1 minute
5 minutes

Is simple pluralization best practice, or is there any better approach?

Overriding/augmenting named format properties

Currently named formats are an either/or proposition -- if you use a named format you cannot pass additional format arguments to it to either add new format args or override named ones. It would be useful to be able to do this in cases where you know some of the specifiers you want at build time but others at run time.

Example:

/*
{
  "formats": {
    "number": {
      "currency": {
        "style": "currency",
        "minimumFractionDigits": 2
      }
    }
  }
}
*/
var price = { value: 42000, currency: 'USD' } ; // assume this comes from some api and is not hard coded

return <IntlNumber format="currency" currency={price.currency}>{price.value}</IntlNumber>;

This will always render it using the current locale's currency specifier because the currency code is ignored.

Standard way of using react-intl dynamically

Hi, I just start using react-intl to integrate i18n in my ReactJS application and have 2 questions because I don't know If I am doing thing "the react-intl way":

A)

I need to select the language in a dynamic way based on navigator.language / navigator.browserLanguage value and providing fallback mechanism.

I have been reading that, at this moment, there is no fallback mechanism implemented in react-intl ([https://github.com//issues/35][1]) and the way of doing it could be to generate complete properties files during the packaging process (webpack, gulp, etc) rather than trying to look it up at runtime.

B)

I need to import the messages file in a dynamic way based on this language variable so I though about using the dynamic import syntax provided by ecmascript 6.

System.import('../i18n/messages/messages-'+lang)
    .then(some_module => {
        alert("Messages found and loaded successfully");
    })
    .catch(error => {
        alert("Messages NOT found.It will be used english by default");
    });

Is this approach correct or is there a more standard approach?

stringified messages paths not found

When you use flat message files where the keys contains dots, they are not properly found. E.g.

var i18n = {
    locales:['en'],
    messages:{
        ui:{
            wall: 'Wall',
            network:'Network',
            my:{
                mp:'My',
                fp:'My'
            },
            events:'Events'
        },
        calc:{
            calculators:'Calculators'
        },
        'ui.complete.profile':'Complete profile'
    }
};

module.exports = i18n;

if the key 'ui.complete.profile' is referenced, this will never be found because the library assumes a dot means a path. In our legacy applications that we are porting to React, all the message keys contain dots. I can imagine a script that converts these files to object structures, but I can also imagine a config-flag that allows you to set this path parsing as an option.

[RFC] React Intl Component Details

A core principal behind FormatJS is providing a declarative way to format data and strings by providing high-level integrations with template/component libraries. The first version of React Intl only have an imperative API provided by ReactIntlMixin, but v1.1.0 will provide a declarative way via React Intl Components. See #23

We feel that formatting data and strings using the declarative form is superior to using the imperative JavaScript APIs, and the plan is to update all the docs to encourage people to use the React Intl Components going forward. Knowning that this is a much different way to use React Intl (luckily everything is backwards compatible) we decided to cut RC releases before making v1.1.0 final.

So far the feedback from people who've been testing out the v1.1.0-rc-* releases has been great! After reflecting on this feedback we still have some open questions that we'd like to settle before cutting the final v1.1.0 release…

Open Questions

1. How should the React Intl Components be named?

@pselden raised a concern about the name of React Intl's module exports for each of the components in #60. Currently on master the exports are named assuming that they will be accessed on the ReactIntl namespace object; i.e., ReactIntl.Number.

While the current naming scheme makes sense when it's written as above, it quickly breaks down in a few ways…

Components with '.'s Feel Awkward to Use

Since JSX compiles down into JavaScript function calls it's perfectly valid to use '.'s when referencing components; e.g., <ReactIntl.Number>, but there's a worry that this might feel odd to use since JSX looks like HTML and you don't see '.'s used in HTML tag names.

ES6 Destructuring and Module Imports

@pselden mentions in #60 how he's been using ES6 destructuring assignments as loving it. But there's a problem with this and the current naming scheme for React Intl Components:

var {Number, Date, Mixin} = require('react-intl');

Built-ins are shadowed! This is horrible, especially for Date which is commonly accessed in JavaScript application code. ES6 Module imports pose a similar problem, but it can be remedied using as:

import {
    Number as IntlNumber,
    Date as IntlDate,
    Mixin as IntlMixin
} from 'react-intl';

While this solves the shadowing problem, it adds a ton of extra typing that will make React Intl annoying to use via ES6 Modules.

For whatever naming scheme that's chosen, we'd like to put more weight behind one with ergonomics that fit with the future direction of JavaScript; i.e. we like the ES6 shorthand destructuring syntax.

[Proposal] Prefixed Exports with Intl

This proposal was brought up by @pselden and the change is sitting in PR #64. It renames all of React Intl's exports to be prefixed with Intl:

  • IntlMixin
  • IntlDate
  • IntlTime
  • IntlRelative
  • IntlNumber
  • IntlMessage
  • IntlHTMLMessage

This proposal keeps the Component names noun-y.

There is a tradeoff for ES5-compatible syntax since you end up with a double "Intl":

var ReactIntl  = require('react-intl');
var IntlNumber = ReactIntl.IntlNumber;

But feels worth it when looking forward to the future (or today when you use a transpiler!):

import {Component} from 'react';
import {IntlNumber} from 'react-intl';

export class Count extends Component {
    render(props, state) {
        return <IntlNumber>{props.count}</IntlNumber>;
    }
}

Note: The React Component class example is from react-future.

[Proposal] Prefix Component Exports with Format

This is similar to the proposal above, but it uses verb-y component names:

  • IntlMixin
  • FormatDate
  • FormatTime
  • FormatRelative
  • FormatNumber
  • FormatMessage
  • FormatHTMLMessage

It's very uncommon to see components with verb-y names, it makes slightly more sense when thinking about the Format prefixed naming scheme in conjunction with the next open question…

2. Should the React Intl Components Be Self-Closing?

Currently, all of the React Intl Components are implemented to accept the value they're formatting as the single child of the component:

<ReactIntl.Number style="percent">{0.9}</ReactIntl.Number>

This is a bit odd and uncommon to see in React since the component's child is not another React component. An alternate approach would be to use a value prop and make the Component self-closing:

<ReactIntl.Number value={0.9} style="percent" />

Self-Closing + Naming Proposals

And this is how it would look in conjunction with the naming proposals from above:

<IntlNumber value={0.9} style="percent" />
<FormatNumber value={0.9} style="percent" />

When using the self-closing approach with a value prop, the FormatNumber naming scheme looks less odd and arguably reads better than IntlNumber.

Message Components as an Exception?

The Message and HTMLMessage components are the exception here and probably benefit from keeping with the current approach where the ICU Message template string is the single child of the component:

var intlData = {
    locales: ['en-US'],
    messages: {
        VISITOR: 'Visitor {count, number}'
    }
};

<App {...intlData}>
    <ReactIntl.Message count={1000}>
        {this.getIntlMessage('VISITOR')}
    </ReactIntl.Message>
</App>

The reason for this is disambiguation of the values the message is formatted with and the message string itself without needing to hijack a prop like message making it unavailable as a variable name inside the ICU message string.

That said, if people prefer the self-closing approach, it would make sense to entertain self-closing messages components as well:

<IntlMessage message={this.getIntlMessage('VISITOR')} count={1000} />
<FormatMessage message={this.getIntlMessage('VISITOR')} count={1000} />

We want to make the declarative way of using React Intl intuitive, and idiomatic. We feel we're close, but want to have solid answers to the above open questions and make these decisions before the final release of v1.1.0.

Please feel free to offer your thoughts on these questions and any alternate ideas you may have. Thanks!

Not installable via npm 2.0

npm ERR! Darwin 14.0.0
npm ERR! argv "node" "/usr/local/bin/npm" "install"
npm ERR! node v0.10.32
npm ERR! npm  v2.1.4
npm ERR! code ETARGET

npm ERR! notarget No compatible version found: react-intl@'>=0.1.0 <0.2.0'
npm ERR! notarget Valid install targets:
npm ERR! notarget ["0.1.0-rc-1","1.0.0-rc-1","1.0.0-rc-2","1.0.0-rc-3","1.0.0"]
npm ERR! notarget
npm ERR! notarget This is most likely not a problem with npm itself.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.