Coder Social home page Coder Social logo

react-polyglot's Introduction

React Polyglot

Provides higher order component for using Polyglot with React

Installation

npm install --save react-polyglot

Usage

react-polyglot exports consists for one wrapper component called I18n, one decorator called translate and one hook called useTranslate. The decorator provides a prop t which is instance of Polyglot.

You are required to wrap your root component with I18n and pass on a locale like en or fr. And messages object containing the strings.

import React from 'react';
import { render } from 'react-dom';
import { I18n } from 'react-polyglot';
import App from './components/app';

const locale = window.locale || 'en';
const messages = {
  "hello_name": "Hello, %{name}.",
  "num_cars": "%{smart_count} car |||| %{smart_count} cars",
}

render(
  <I18n locale={locale} messages={messages}>
    <App />
  </I18n>,
  document.getElementById('app')
);

Then inside App or a child component of App you can do:

import React from 'react';
import { translate } from 'react-polyglot';

const Greeter = ({ name, t }) => (
  <h3>{t('hello_name', { name })}</h3>
);

Greeter.propTypes = {
  name: React.PropTypes.string.isRequired,
  t: React.PropTypes.func.isRequired,
};

export default translate()(Greeter);

or with React Hooks:

import React from 'react';
import { useTranslate } from 'react-polyglot';

export default const Greeter = ({ name }) => {
  const t = useTranslate();

  return (
    <h3>{t('hello_name', { name })}</h3>
  );
};

Greeter.propTypes = {
  name: React.PropTypes.string.isRequired
};

Live Examples

Minimal example using class components

https://codesandbox.io/s/mq76ojk228

Advance example with user changeable locales

https://codesandbox.io/s/px8n63v0m

How to provide context in your tests

Use a simple helper to wrap your components in a context.

export const wrapWithContext = function (component, context, contextTypes) {
  const wrappedComponent = React.createClass({
    childContextTypes: contextTypes,
    getChildContext() {
      return context;
    },
    render() {
      return component;
    },
  });
  return React.createElement(wrappedComponent);
}

Then use it inside your tests.

import React from 'react';
import { renderToString } from 'react-dom/server';
import Polyglot from 'node-polyglot';
import Greeter from './greeter';
import { wrapWithContext } from './helpers';

const polyglot = new Polyglot({
  locale: 'en',
  phrases: {"hello_name": "Hello, %{name}."},
});

const greeterWithContext = wrapWithContext(
  <Greeter name="Batsy" />,
  { t: polyglot.t.bind(polyglot) },
  { t: React.PropTypes.func }
);

// use greeterWithContext in your tests
// here it is shown how to use it with renderToString
console.log(renderToString(greeterWithContext));

Release History

Check the Releases tab.

react-polyglot's People

Contributors

deepsourcebot avatar dependabot[bot] avatar feego avatar matheusmoreira-hotmart avatar nayaabkhan avatar neoreyad avatar pmmmwh avatar rdiazv avatar rouflak 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

Watchers

 avatar  avatar  avatar

react-polyglot's Issues

Does this work for React.Component?

@nayaabkhan Thank you so much for this project. Really appreciate your work.

Following the sample code everything works well with pure functions but whenever I try to use it with a class extending React.Component, it fails to access t. It should be available with this.props.t, shouldn't it?

...
import { translate } from 'react-polyglot'
...
export class MyComponent extends Component {
   render() {
      console.log(this.props.t('test')
   }
}
...
export default translate()(MyComponent)

Any idea why the translate function (t) is not injected to the props?

Describe how to provide t in tests

Hi,

how can we provide provide the t-function in a test? For example, consider the following component:

const C = translate()(({ t }) => (
  <div>
    {t('hello')}
  </div>
));

For example, I use jest:

test('CTest', () => {
  const wrapper = shallow(
    <C />
  );
});

Error:

Warning: Failed context type: The context `t` is marked as required in `_translate`, but its value is `undefined`.
          in _translate

When trying to provide context with t:

const polyglot = new Polyglot({ phrases: {'hello': 'Hello'} });
const context = {
  context: { t: polyglot.t },
  childContextTypes: { t: PropTypes.func },
};

const wrapper = shallow(
      <Footer />, context
    ).dive();

I get this error:

TypeError: Cannot read property 'phrases' of undefined

Trying a HOC:

import React from 'react';
import I18n from 'react-polyglot';
const locale = 'en';
const messages =  {'hello': 'Hello'};

const I18nProvider = ({ component: Component }) => (
    <I18n locale={locale} messages={messages}>
        <Component />
    </I18n>
);
const shallowWithT = node => shallow(<I18nProvider comopnent={node} />, context)
  .dive(context);

// in test
const wrapper = shallowWithT(
  <Footer />
);

I get this error:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.

Expose Polyglot.t() to `onMissingKey` to allow substitutions

Currently, react-polyglot allows to use onMissingKey from node-polyglot, see:
https://github.com/airbnb/polyglot.js/blob/6c10c6f3eacec8f23deb4635dfafca862167161e/index.js#L406

Unfortunately, since there is no exposed translation function that allows substitutions, the passed onMissingKey function will have to implement its own substitution logic, effectively using node-polyglot exports. Here is an example of such implementation:

  const onMissingKey = (key: string, substitutions?: InterpolationOptions) => {
    const translation = get(translations['en'], key)
    return transformPhrase(translation, substitutions)
  }

It would be great to make the translation function available so that implementors of onMissingKey can benefit from the already available translation context.

Proposed solutions:

  1. Augment onMissingKey with an additional t parameter (probably not the best for arity reasons, as locale will have to be passed)
  2. Export the transformPhrase or Polyglot.t translation function - this way, there would be no back and forth switching between the two libraries needed to implement this.

Note that if we go with this, InterpolationOptions will need to be exported, as onMissingKey is typed like so, and implementations using TS need to type it if they enabled noImplicitAny in their tsconfig:

(property) PolyglotOptions.onMissingKey?: ((key: string, options?: InterpolationOptions | undefined, locale?: string | undefined) => string) | undefined

Happy to implement it if that's something of interest! I could also document it/add examples as documentation is missing for it on both node-polyglot and on this library.

Update locale and messages on the fly

Do you think it would be possible to make i18n updates on the fly ?

For instance, when the app starts, currant lang is en and the Greeter component displays Hello rlebosse.

But at a particular time, we decide we want to switch from en to fr locale and display Bonjour rlebosse by updating props <I18n locale={locale} messages={messages}>.

Thank you for your answer

Get rid of deprecated componentWillReceiveProps

componentWillReceiveProps is deprecated and will be removed in React 17.

It's currently being used to update the internal node-polyglot instance when the <I18n> component's props change:

componentWillReceiveProps(newProps) {
if (newProps.locale !== this.props.locale) {
this._polyglot.locale(newProps.locale)
}
if (newProps.messages !== this.props.messages) {
this._polyglot.replace(newProps.messages)
}
}

We need to find a future-proof way of updating the internal node-polyglot instance.

Npm install won't install the lib folder

When I run the npm install --save react-polyglot command, it correctly installs the node module folder but the lib folder is missing in the directory.

I think it is due to the prepublish script. Maybe something has gone wrong with it.

Thx

Pass node-polyglot options as props

Hey!

I'm using this in a project and so far it works great! :)

But <I18n> does not seem to accept additional options for node-polyglot.
For example there is no way to configure allowMissing and onMissingKey.

I think we should be apple to pass options as props, or maybe pass an object to be forwarded to node-polyglot?

<I18n allowMissing onMissingKey={() => console.log('Missing key')}>

or

<I18n options={{ allowMissing: true, onMissingKey: () => console.log('Missing key') }}>

What do you think?

Thanks!

Passing JSX to the `t` Function

Hello,

First of all, thanks for this library. I use it in a lot of my projects!

Here is my use-case: I'm trying to pass a React component to the t function without having to break it into chunks. Here's an example of what I currently have:

{t('Meet and collaborate using the')}{' '}
  <Link href="#">
    {t('redesigned experience')}
  </Link>

But this means having to localize/translate 2 separated strings. My goal would be to make it work like this:

{t(`Meet and collaborate using the <Link href="#">redesigned experience</Link>`)}

I've already tried the following approach:

{t(`Meet and collaborate using the %{reactComponent}`, {
  reactComponent: <Link href="#">redesigned experience</Link>,
})}

But this outputs Meet and collaborate using the [object Object]

Any idea on how to achieve this? Thanks!

react-polygot: Warning: Missing translation for key: '...'

Hello, I keep on getting warnings regarding my keys. I followed the setup exactly as done by the following project:

https://github.com/mikeludemann/react-international/tree/957980e5c504eefb8b419cd090ec911a187ad929/public

(Meaning I have my translations inside a translation folder inside public folder).

I get these errors by default after I clone the above repo, do and npm install and an npm start. There are warnings in the console even though everything is working as it's supposed. Is there a way to disable these warnings?

Thank you for the great pacakge

Multiple instances of Polyglot upon updating locale and phrases

Updating locale and phrases on the fly causes the plugin to instance Polyglot multiple times, which can lead to a variety of languages on the same screen.

How can i test this?
Simply creating a React application with deeply nested components, and updating both locale and phrases should be enough.

What is the solution?
Stop creating instances of Polyglot on componentWillReceiveProps in i18n.js. Polyglot's locale and replace methods should be used instead.

Sorry for my bad english. I'll provide a PR fixing this in the upcoming minutes.

Types for Typescript

Hi,

I have wonder why this library has no types on DefinitelyTyped. It would be nice to have typed HOC translate for instance. What do you think @nayaabkhan ?

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.