• Stars
    star
    232
  • Rank 167,201 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A simple and powerful package for translate your react applications using react-redux.

Description

redux-i18n is a simple yet powerful package to translate your react applications using react-redux.

npm version downloads

Installation

npm i redux-i18n --save

or

yarn add redux-i18n

Features

  • Translate literals.
  • Pluralize literals.
  • Designed for react-redux.
  • Compatible with Immutable.js.
  • Export translations to POT files (make your translations with Poedit).
  • Import translations from .PO files to translations.js object (for use in your project).
  • Add comments for translators.

Requirements

  • node >= 4.0.0

Overview

redux-i18n offers your app the t() function to translate literals.

The t() function is available in the components of your app via React context. To achieve this you need to wrap your app into the <I18n /> component from redux-i18n that provides for the context. Furthermore, for all components that want to use the t() function you need to define contextTypes, e.g.:

// import ...
import PropTypes from 'prop-types'

class MyComponent extends React.Component {
  render() {
    return <div>{this.context.t('Hello World!')}</div>
  }
}

MyComponent.contextTypes = {
  t: PropTypes.func
}

If contextTypes is not defined, then context will be an empty object.

The t() function takes up to three arguments t(textKey [, params, comments]), where textKey is either the string to be translated or --- for pluralization --- an object as defined below.

For setting the language in the redux store redux-i18n offers an action creator setLanguage.

To manage the translations in your React app, redux-i18n supports two choices:

  1. load all your translations into a one big JS object
  2. load your translations into a slice of your redux store

For the latter redux-i18n provides an action function creator setTranslations. As setTranslations is an action function creator you need to add redux-thunk to your middleware for it to work.

redux-i18n supports your store in plain JavaScript structures, but also if it is managed by help of immutable.js.

Finally, redux-i18n offers scripts to generate a translations object from po files that can be managed in Poedit.

Usage

The package provides a parent component to encapsulate your application as well as helpers functions to translate your project.

// import ...
import I18n from 'redux-i18n'
// with Immutable.js:
import I18n from 'redux-i18n/immutable'

import { translations } from './translations'

class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <I18n translations={translations}>
          <App />
        </I18n>
      </Provider>
    )
  }
}

Where translations is a dictionary similar to this:

export const translations = {
  es: {
    'Translate this text': 'Traduce este texto',
    'Hello {n}!': 'Hola {n}!'
  }
}

You can also set the initial language with the initialLang prop:

<I18n translations={translations} initialLang="es">
  <div>
    <h1>My Project</h1>
    {this.props.children}
  </div>
</I18n>

If you have partial translations, this means that you don't have your translations at 100% and you want to show untranslated literals in an other language, you can use the fallbackLang prop.

<I18n translations={translations} initialLang="de" fallbackLang="en">
  <div>
    <h1>My Project</h1>
    {this.props.children}
  </div>
</I18n>

In this case, if you want to show this translations:

<div>{this.context.t('_hello_')}</div>

And this isn't in "de" language, it will show in "en".

Redux Reducer

The language state is managed in a slice of the store named i18nState. Therefore, you have to add the i18nState reducer in your combineReducers.

import { otherreducers } from './Yourproject'

import { i18nState } from 'redux-i18n'
// with Immutable.js:
import { i18nState } from 'redux-i18n/immutable'

const appReducer = combineReducers({
  otherreducers,
  i18nState
})

The current language is contained in the lang key of i18nState.

The i18nState is initially defined as

const defaultI18nState = {
  lang: 'en',
  translations: {},
  forceRefresh: false
}

// immutablejs
const defaultI18nState = new Map({
  lang: 'en',
  translations: {},
  forceRefresh: false
})

When you map your state to props with connect you can also access the lang attribute in your components:

export default connect(state => ({
  lang: state.i18nState.lang,
}))(Home)

// with Immutable.js:
export default connect(state => ({
  lang: state.getIn(['i18nState', 'lang']),
}))(Home)

Translate literals

You can access the functions of <I18n /> using your component's context. For example:

Home.contextTypes = {
  t: PropTypes.func.isRequired
}

...you will then be able to use the t() method in your component.

render() {
  return (
    <div>
      <strong>Your current language, is: {this.props.lang}</strong><br/>
      {this.context.t("Translate this text")}<br/>
      {this.context.t("Hello {n}!", {n: "World"})}<br/><br/>
      <button onClick={this.changeLanguage.bind(this)}>Change Language</button>
    </div>
  )
}

You can also use the t() function to change date formats

export const translations = {
  de: {
    'YYYY-MM-DD': 'DD.MM.YYYY'
  }
}
render() {
  let today = moment()
  return (
    <div>
      {today.format(this.context.t("YYYY-MM-DD"))}
    </div>
  )
}

Add comments for translators.

render() {
  return (
    <div>
      {this.context.t("Translate this text", {},
                      "This is a comment for translators.")}
      {this.context.t("Hello {n}!", {n: "Cesc"},
                      "This is another comment.")}
    </div>
  )
}

Here's how Poedit will show the comments:

Poedit screenshot

HTML Object as parameter

const user = { name: 'World' }
const name = <span>{user.name}</span>
return <div dangerouslySetInnerHTML={{ __html: context.t('Hello {name}', { name: name }) }} />

Result:

Hello <span>Cesc</span>

Notice that for security reasons we can't print html code directly, which is why we need to use the "dangerouslySetInnerHTML" method for that.

Stateless components

Example:

const Foo = ({}, context) => <h1>{context.t('Hello World')}</h1>

Pluralize

To use plurals in your translations.

<div>{this.context.t(['una noche', '{n} noches', 'n'], { n: 1 })}</div>

Pass an array instead of a string as first parameter. The first element is a singular term, the second is the plural form and the last one is an object used to set the quantity.

After extracting the translations to a POT file and opening it with Poedit you will see the following:

Poedit screenshot

Also the translations object allows to set an options node. There you can set a plurals form rule and a plurals number. Also, you can suppress warnings logged in console. For example:

export const translations = {
  es: {
    'Translate this text': 'Traduce este texto',
    'Hello {n}!': 'Hola {n}!'
  },
  options: {
    plural_rule: 'n > 1',
    plural_number: '2',
    suppress_warnings: true // defaults to false
  }
}

When the translations are generated from po import file, this node is created automatically.

Note: Versions >=1.5.10 allow to use all existing pluralization rules: http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html

Change language

Use the setLanguage action.

import {setLanguage} from "redux-i18n"

componentWillMount() {
  this.props.dispatch(setLanguage("es"))
}

If you work with combined languages like "es-ES", "en-GB", but your translations object doesn't include those properties...

export const translations = {
  "es": {
    ...
  },
  "en": {
    ...
  }
}

...redux-i18n will fallback on the closest property. In this case, "es" or "en".

Extract/Import scripts

redux-i18n includes a script to extract your translation strings to a .pot template which you can use in Poedit, and another to import strings from po files to a translation.js.

Add the scripts in your package.json for this purpose:

"scripts": {
  "extract": "i18n_extract",
  "import": "i18n_import"
}

You can then run the following commands in your terminal:

npm run extract
npm run import

Extract texts and build template.pot

npm run extract

By default, this script will search for all literals inside your src folder with a regular expression and build a locales/template.pot file. This file can then be used in Poedit to build en.po, es.po, etc. files.

If you want to set other source folder, you can use the --source switch.

"scripts": {
  "extract": "i18n_extract --source=mysourcefolder",
  "import": "i18n_import"
}

Or if you want to export your locales to a different folder...

"scripts": {
  "extract": "i18n_extract --source=mysourcefolder --locales=mylocalesfolder",
  "import": "i18n_import"
}

By default this command find in all .js and .jsx file extensions, but you can customize it with fexts parameter. Check out this example:

"scripts": {
  "extract": "i18n_extract --fexts=js,jsx,coffee",
  "import": "i18n_import"
}

The default regular expression will search all occurrences of this.context.t string, but you can also supply your own custom pattern, as in the following example:

export default function App({ aProp, bProp }, { t: translate }) {
  return <div>{translate('Hello world!')}</div>
}

You will then need to set the --pattern flag in package.json:

"scripts": {
  "extract": "i18n_extract --pattern=translate",
  "import": "i18n_import"
}

Import .po files

When your translators are done translating your terms, you can import your po files running the import script:

npm run import

This script read all po files inside your locales folder, extract all translations and build a src/translations.js that you can then use in your project.

Your .po files must define header language, check mininal format for more information.

You can also set another locales folder:

"scripts": {
  "extract": "i18n_extract --source=mysource --locales=mylocales",
  "import": "i18n_import --locales=mylocales"
}

Or, save translation.js to a different location:

"scripts": {
  "extract": "i18n_extract --source=mysource --locales=mylocales",
  "import": "i18n_import --locales=mylocales --translations=myfolder"
}

You can also change the encoding for your extraction from PO (default is iso-8859-1)

"scripts": {
  "extract": "i18n_extract --source=mysource --locales=mylocales",
  "import": "i18n_import --encoding=utf-8"
}

Async translations

When applications grow, translations tend to bigger as well, adding a lot to the overall size of the js bundle.

You can set an empty translations object to the <I18n/> component and set the useReducer prop to true to use the store as the source of strings. For example:

<Provider store={this.store}>
  <I18n translations={{}} useReducer={true}>
    <MainApp />
  </I18n>
</Provider>

Then you can use the setTranslations action.

import { setTranslations } from 'redux-i18n'
api.get('...').then((r) => this.props.dispatch(setTranslations(r.translations)))

You can pass a second parameter to the action to set the language. Depending on your response's structure, it could look like this:

api.get('...').then((r) => this.props.dispatch(setTranslations(r.translations, 'en')))

Since version 1.5.1 is possible pass a dictionary as a second param with some options. This allows us set more functionalities to method.

  • preserveExisting (bool): If is true, the translations received does merge with existing translations.
  • language (string): Language code

Some examples:

setTranslations(newTranslations, { preserveExisting: true })
setTranslations({ Hello: 'Hallo' }, { language: 'de' })

InitialState

Sometimes language is set initially by the redux store creation, or in an isomorphic way. In this case, you can set the initialized prop to stop the I18n provider from dispatching an action.

HOC

If you want to isolate the use of context from your components, you can import the Localize Hoc to provide the translate function as a prop to your component. For example:

import { localize } from 'redux-i18n'

class SomeComponent extends Component {
  render() {
    return this.props.t('hello world')
  }
}

export default localize()(SomeComponent)

You can also change the name of the provided prop:

import { localize } from 'redux-i18n'

class SomeComponent extends Component {
  render() {
    return this.props.translate('hello world')
  }
}

export default localize('translate')(SomeComponent)

Please, if you like my package, don't forget to rate it. Click on the "star"!

More Repositories

1

react-native-keyboard-aware-scroll-view

A ScrollView component that handles keyboard appearance and automatically scrolls to focused TextInput.
JavaScript
5,218
star
2

react-native-button

A React Native button component customizable via props
JavaScript
750
star
3

puput

A Django blog app implemented in Wagtail
Python
603
star
4

react-native-version-number

Gets the version number and build number of your app.
Java
380
star
5

docker-thumbor

Docker image for thumbor. Detectors, optimizers, lazy detection and separate docker for remotecv.
Smarty
292
star
6

react-native-item-cell

React Native default iOS item cell
JavaScript
72
star
7

react-native-floating-label

A React Native floating label text input for tcomb-form-native
JavaScript
66
star
8

kaneda

Configurable Python library for metrics collection
Python
54
star
9

kubernetes-charts

Helm Charts to deploy Django apps in Kubernetes
Mustache
51
star
10

django-yubin

Send e-mails asyncronously using Celery
Python
48
star
11

go-aws-elb-log-analyzer

Download logs from ELB and join in a sorted file
Go
30
star
12

react-native-navigator-wrapper

A React Native Navigator component wrapper that implements nested navigators for both push and modal transitions
JavaScript
30
star
13

sauron

Sauron is a Django Channels app and Micropython IoT device to monitor toilet status
Python
23
star
14

django-hattori

Command to anonymize sensitive data
Python
18
star
15

transmanager

TransManager is a simple django app to deal with the translations tasks of the models content based on django-hvad.
HTML
18
star
16

pytest-checkipdb

Plugin to check if there are ipdb breakpoints left
Python
18
star
17

django-kaio

Class based settings for Django projects that can be read from multiple sources
Python
17
star
18

rasengan

Rasengan is a command-line tool for automated testing of multiple kind of integrations tests for domains, with a simple and flexible YAML definition syntax.
Python
15
star
19

docker-puput

Docker image for Puput blog
Python
14
star
20

wordpress-to-puput

Import your Wordpress blog data into Puput
Python
13
star
21

react-native-meneame

A meneame.net client for iOS and Android built with React Native
JavaScript
11
star
22

react-native-sumup

Sumup SDK for React Native
Objective-C
11
star
23

react-native-section-menu

A multi-platform React Native sectioned menu
JavaScript
10
star
24

tcomb-form-native-json-schema

A bridge between tcomb-json-schema and tcomb-form-native
JavaScript
10
star
25

react-native-options-button

A bottom animated options button
JavaScript
9
star
26

wagtail-jsonschema-forms

Generate JsonSchema Forms from Wagtail's forms and validate it
Python
8
star
27

docker-django

Django base Dockerfile. Process managed by circus. Config with envtpl.
Shell
7
star
28

puput-demo

An example blog app using Puput
Python
7
star
29

docker-rundeck

Shell
6
star
30

AssetsGenerator

Simple Python script to generate iOS icon image assets
Python
6
star
31

sshail

SSHail is a tool to generate on-demand SSH jails for users using Docker.
Python
6
star
32

docker-circusbase

Docker base image for processes managed with circus. Config parameters with envtpl.
Shell
6
star
33

kumostatus

Create CloudWatch dashboards in mobile html version
Python
6
star
34

docker-tomcat6

Docker container for Legacy Tomcat6 / Java6 app server
Smarty
5
star
35

django-email-foundation

Package for help you to make ease build email templates in your project.
Python
5
star
36

thumbor_talk

CSS
4
star
37

rxp-python

The official Realex Payments Python SDK
4
star
38

django-object-authority

Package to authorize actions (CRUD) to users over concrete items.
Python
4
star
39

django-apslutils

Herramientas y librerรญas varias que utiliza el equipo de APSL para sus proyectos
JavaScript
4
star
40

pycharm-live-templates

Custom live templates
4
star
41

django-behind-lb

Behind-LB is a very simple and efficient Django middleware to obtain the client IP address when the project runs behind a trusted load balancer.
Python
4
star
42

page-size-check

An utility to check the size of your pages and resources used
Python
4
star
43

remotecv_aws

Module to load s3 images in remotecv
Python
3
star
44

apsl.github.io

APSL GitHub page
JavaScript
3
star
45

docker-lamp

Docker APSL base project for LAMP apps
Smarty
3
star
46

docker-bareos-bat

๐Ÿ‹ Dockerized bareos-bat
Dockerfile
3
star
47

docker-devpi

Nginx
3
star
48

pycon-fastapi-example

Python
3
star
49

redux-action-api-utils

Redux actions utility for creating and handling REST API requests
JavaScript
3
star
50

zinnia-to-puput

Import your Zinnia blog data into Puput
Python
2
star
51

docker-postgres

Docker image for postgresql: configure with enviroment variables, postgis and wal-e
Smarty
2
star
52

django-month-filter

Month filter for admin
Python
2
star
53

generator-apsl-angular

This generator extends the default yo generator-angular in order to scaffold angular projects according to APSL dev standards.
JavaScript
2
star
54

docker-tomcat

Docker base container for Tomcat app server
Smarty
2
star
55

docker-wordpress

Wordpress on LAMP managed with circus. Wordpress config parameters managed with envtpl. Keys generated if not found in env.
Smarty
2
star
56

blogger-to-puput

Import your Blogger blog data into Puput
Python
2
star
57

postgresql-wal-e-nagios

Python
2
star
58

docker-tomcat5

Docker container for Legacy Tomcat5 / Java5 app server
Shell
1
star
59

docker-gcloud

gcloud tool with keys authentication
Shell
1
star
60

redis-cluster-nagios

Script python to control the status of a master/slave redis cluster.
Python
1
star
61

deploy_talk

CSS
1
star
62

react-native-scrum-pocket

Scrum Pocket's source code, made with React Native.
JavaScript
1
star
63

webtest

Helper class for selenium tests. Helps running single test, or multi-mechanize tests.
Python
1
star
64

salt-shellshock

Salt recipe for shellshock (CVE-2014-6271)
Shell
1
star
65

archiclean

Utility for cleaning apache archiva repository versions and snapshots
Python
1
star
66

sepakit

Converts AEB 19.14 Direct Debit TXT file to SEPA XML (Core scheme)
Go
1
star
67

python-branch

A branch.io client in Python
Python
1
star
68

docker-nginx-static

Nginx
1
star
69

ecsh

Cli tool to access Amazon ECS containers with a shell
Python
1
star
70

docker-drupal

Drupal on LAMP managed with circus. Drupal config parameters managed with envtpl. Keys generated if not found in env.
Shell
1
star
71

docker_talk

Docker intro presentation
CSS
1
star
72

ecs-scheduled-task-updater

Simple script to update the task definition of a scheduled task to the latest version
Python
1
star
73

docker-java

Docker base project for java Apps
1
star