Skip to main content
Version: 1.16

Internationalization

Description

The @regards/i18n (web_modules/utils/i18n) module holds components and tools designed to simplify the internationalization of all messages in the REGARDS frontend.

The REGARDS internationalization implementation uses react-intl library.

Dependencies

To use the REGARDS I18nProvider you must add the here under packages to your package.json dependencies:

  • @regardsoss/i18n
  • react-intl

How to

Internationalize text in REGARDS

In components with i18n context (see later sections), you can retrieve internationalized messages using:

  • this.context.intl.formatMessage method, which produces a string out of the two parameters:
    • First parameter is an object, where field id is the message key
    • Second parameter is an object, where each field key is the value key in messages (allowing messages with dynamic values)

Notes :

  • To use the formatMessage method of the react-intl library, you need to define the react component context with the react-intl properties. To do so, you can use the i18nContextType of the @regardsoss/i18n package.
  • Value returned by formatMessage is a string (and not a React.Element).
import { i18nContextType } from '@regardsoss/i18n'

export class ExampleComponent extends React.Component {

static contextTypes = {
...i18nContextType,
}

render() {
const { intl: { formatMessage } } = this.context
return (
<div>
<span>{formatMessage({ id: 'example.message' })}</span>
</div>
)
}
}

Connect with internationalization context

In REGARDS, the internationalization context can be provided to children by using either:

  • I18nProvider component
  • withI18n decorator function

Those two methods are detailed in sections below.

What's stackCallingContext?

I18N connectors also define an optional parameter/property called stackCallingContext (false by default).
That property, when true, indicates that the new context and parent context should be merged. It results in providing both parent and new context messages to children. When exploring REGARDS code, that method is frequently encountered, especially in common components, as it allows the calling component defining children using calling context messages while API components still access messages in their own context.*

Using I18nProvider

I18nProvider component provides internationalization context to its React children as demonstrated in example below. It defines the following properties:

  • messages : an object, where first level key is locale (like 'en' or 'fr') and second level key are messages keys. Most of the time, we import directly the messages folder index.js file, as it exports {en:enMessage, fr:frMessages}, which matches expected shape.
  • stackCallingContext: an optional boolean, false by default. See note in parent section for more detail.

Example :

import { I18nProvider } from '@regardsoss/i18n'
import messages from '../i18n' // will contain {en:..., fr:...}

export class ExampleContainer extends React.Component {

render() {
return (
<I18nProvider messages={messages}>
<ExampleComponent />
</I18nProvider>
)
}
}

In the previous example, ExampleComponent will be able to access the i18n through context but ExampleContainer will not. Indeed context is defined for I18NProvider children, in the React meaning.

For instance, in the following React tree, B and C can access messages context, but A can not.

<A>
<I18nProvider messages={messages}>
<B>
<C />
</B>
</I18nProvider>
</A>

Using withI18n

To use the REGARDS withI18n decorator method, you need to export the component decorated with that method. It defines the following parameters (matching with I18NProvider properties described before):

  • messages
  • stackCallingContext

Example:

import { withI18n } from '@regardsoss/i18n'
import messages from '../i18n'

class ExampleContainer extends React.Component {

render() {
const { intl: { formatMessage } } = this.context

return (
{formatMessage({ id: 'example.message' })}
)
}
}

export withI18n(messages)(ExampleContainer)

The use of withI18n(messages)(ExampleContainer) means that messages context will be defined for ExampleContainer and all its children. Therefore, if we define the contextTypes in this container, it will be able accessing the messages through its context.

The instruction import messages from '../i18n corresponds to messages files import explained in the next section.

I18n messages files

As explained in the previous sections, the I18nProvider component or withI18n method expects to receive an object that maps a list of locales onto a list of messages. For each locale object, keys will be the message key and value the internationalized message. In REGARDS, by design, each locale messages dictionnary is defined in a file named messages.{LOCALE}.i18n.js, where {LOCALE} is locale shorthand ('en', 'fr').

The example below illustrates a messages.en.i18n.js file content:


import { Locales } from '@regardsoss/form-utils'

const messages = {
...Locales.en, // form messages, required when dealing with forms
'example.message' : 'Example message to display',
'other.example.message' : 'Other example message to display'
}

export default messages

And here is the similar example for a messages.fr.i18n.js file content:


import { Locales } from '@regardsoss/form-utils'

const messages = {
...Locales.fr, // form messages, required when dealing with forms
'example.message' : 'Message d\'exemple à afficher',
'other.example.message' : 'Un autre message d\'exemple à afficher'
}

export default messages

To regroup the multiple language files, we usually create an index.js file as :

import en from './messages.en.i18n'
import fr from './messages.fr.i18n'

module.exports = {
en,
fr,
}

That file exports precisely what the messages parameter/property consumes when using withI18n or I18nProvider.

Use parameter in messages

With the reac-intl library, it is possible to use parameters in internationalizzed message.
Let's illustrate how to create it.

  • Create a parametrized message
'example.message.with.parameter': 'Hello {name} ?'
  • Provide parameter when rendering
  static contextTypes = {
...i18nContextType,
}

render() {
const { intl: { formatMessage } } = this.context
const name = 'john'
return (
<div>
<span>{message}</span>
{formatMessage({ id: 'example.message.with.parameter' }, { name })}
</div>
)
}

You can also customize the displayed message using the provided value.

For string parameters, you can use select:

  'example.message.with.string.parameter': 'Hello {name, select, john {John Doe} other {you}}',

For boolean parameters, you can use select:

  'example.message.with.boolean.parameter': 'Sir, {accepted, select, true {please enter in the room} other {you cannot come in this place}}.',

For integer parameters, you can use plural:

  'example.message.with.integer.parameter': `{count, plural,
=0 {None}
one {Single entity}
other {Many entities}
}`,

More informations

As the REGARDS I18nProvider is used only to provide messages to the react-intl library all components that have the message context can use any react-intl functionality. You can refer to the official documentation to see more functionalities like Date internationalization or HTML display.