5

Currently while using babel-plugin-react-intl, separate json for every component is created with 'id', 'description' and 'defaultMessage'. What I need is that only a single json to be created which contains a single object with all the 'id' as the 'key' and 'defaultMessage' as the 'value'

Present situation:

ComponentA.json

[
  {
    "id": "addEmoticonA",
    "description": "Add emoticon",
    "defaultMessage": "Insert Emoticon"
  },
  {
    "id": "addPhotoA",
    "description": "Add photo",
    "defaultMessage": "Insert photo"
  }
]

ComponentB.json

[
  {
    "id": "addEmoticonB",
    "description": "Add emoji",
    "defaultMessage": "Insert Emoji"
  },
  {
    "id": "addPhotoB",
    "description": "Add picture",
    "defaultMessage": "Insert picture"
  }
]

What I need for translation.

final.json

{
  "addEmoticonA": "Insert Emoticon",
  "addPhotoA": "Insert photo",
  "addEmoticonB": "Insert Emoji",
  "addPhotoB": "Insert picture"
}

Is there any way to accomplish this task? May it be by using python script or anything. i.e to make a single json file from different json files. Or to directly make a single json file using babel-plugin-react-intl

2 Answers 2

8

There is a translations manager that will do this.

Or for a custom option see below


The script below which is based on this script goes through the translation messages created by babel-plugin-react-intl and creates js files that contain all messages from all components in the json format.

import fs from 'fs'
import {
  sync as globSync
}
from 'glob'
import {
  sync as mkdirpSync
}
from 'mkdirp'
import * as i18n from '../lib/i18n'

const MESSAGES_PATTERN = './_translations/**/*.json'
const LANG_DIR         = './_translations/lang/'
  // Ensure output folder exists
mkdirpSync(LANG_DIR)

// Aggregates the default messages that were extracted from the example app's
// React components via the React Intl Babel plugin. An error will be thrown if
// there are messages in different components that use the same `id`. The result
// is a flat collection of `id: message` pairs for the app's default locale.
let defaultMessages = globSync(MESSAGES_PATTERN)
  .map(filename => fs.readFileSync(filename, 'utf8'))
  .map(file => JSON.parse(file))
  .reduce((collection, descriptors) => {
    descriptors.forEach(({
      id, defaultMessage, description
    }) => {
      if (collection.hasOwnProperty(id))
        throw new Error(`Duplicate message id: ${id}`)

      collection[id] = {
        defaultMessage, description
      }
    })
    return collection
  }, {})

// Sort keys by name
const messageKeys = Object.keys(defaultMessages)
messageKeys.sort()
defaultMessages = messageKeys.reduce((acc, key) => {
  acc[key] = defaultMessages[key]
  return acc
}, {})

// Build the JSON document for the available languages
i18n.en = messageKeys.reduce((acc, key) => {
  acc[key] = defaultMessages[key].defaultMessage
  return acc
}, {})
Object.keys(i18n).forEach(lang => {
  const langDoc = i18n[lang]
  const units = Object.keys(defaultMessages).map((id) => [id, defaultMessages[id]]).reduce((collection, [id]) => {
    collection[id] = langDoc[id] || '';
    return collection;
  }, {});
  fs.writeFileSync(`${LANG_DIR}${lang}.json`, JSON.stringify(units, null, 2))
})

Sign up to request clarification or add additional context in comments.

Comments

0

You can use babel-plugin-react-intl-extractor for aggregate your translations in single file. Also it provides autorecompile translation files on each change of your messages.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.