Wk-notes-03-16-i18n-solution

i18n Solution

Solution

Provider provides intl dictionary, Consumer takes the intl and translate() it with hardcoded (nested)id, and fallback,

Pluralise and templating:

In dictionary, each fields supports plural

// Dictionary:
"passengers": { 
  "none":"No passengers", 
  "one":"One passenger", 
  "many":"{{count}} passengers"
}

// Component:
<Text id="passengers" plural={0} /> // "No passengers"
<Text id="passengers" plural={1} /> // "One passenger"
<Text id="passengers" plural={2} fields={{ count: 2 }} /> // "2 passengers"

// HOC 
withIntl((t) => {
    return t('passengers', "fallback", { plural:2 })
})

Basic function

Context

createContext({ dictionary: null, highlight: false });

Provider:

<IntlContext.Provider value={{ highlight, dictionary }}>{children}</IntlContext.Provider>

Consumer:

<IntlContext.Consumer>(intl) => {children}</IntlContext.Consumer>

or

useContext(IntlContext)

Detail in consumer:

  • Dealing with hightlight

  • Expose just enough api

  • call translate()

const intl = useContext(IntlContext);
const t = useCallback(
  (id, fallback, opts = {}) => {
    const highlight = opts.highlight != null ? opts.highlight : intl.highlight;
    const value = translate(id, intl && intl.dictionary, opts.fields, opts.plural, fallback);
    return highlight ? <Highlight id={id} value={value} fallback={fallback} /> : value;
  },
  [intl]
);

translate() from intl

translate(
  id: string, 
  dictionary: object, 
  fields: object, 
  plural: number, 
  fallback: string
) => {
  let value = dictionary && delve(dictionary, id);

  if ((plural || plural === 0) && value && typeof value === 'object') {
    if (Array.isArray(value)) {
      value = value[plural] || value[0];
    } else if (plural === 0 && value.none != null) {
      value = value.none;
    } else if (plural === 1 && (value.one != null || value.singular != null)) {
      value = value.one || value.singular;
    } else {
      value = value.some || value.many || value.plural || value.other || value;
    }
  }

  return (value && template(value, fields, dictionary)) || fallback || null;
}

return translated string.

Last updated