diff --git a/README.md b/README.md index 485c969..0605e3f 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ * Supports globs * Supports flow type * Supports string concatenation, e.g. `gettext('Foo ' + 'Bar')` (useful for wrapping into multiple lines) +* Supports dynamically overriding message contexts. ## Usage @@ -301,6 +302,46 @@ Does not break long strings into several lines Default: `false` +##### `overrideContext` + +Overrides the context present in a component/function. + +This allows for dynamic creation of messages for contexts. + +Ex: + +``` + +``` + +Configured with + +``` +const messages = extractMessages(code, { + overrideContext: ['male', 'female'], +}) +``` + +Would result in + +``` +#: src/App.js:37 +msgctxt "male" +msgid "{{ name }} is very tall" +msgstr "" + +#: src/App.js:37 +msgctxt "female" +msgid "{{ name }} is very tall" +msgstr "" +``` + +This allows your translation teams to create context specific translations, especially useful for languages that have variations based on gender. + + ### Configuration file The `react-gettext-parser` CLI accepts a `--config ` argument. This should point to a JavaScript or JSON file that exports an object with any or all of the available options as root properties. Here's an example: diff --git a/package.json b/package.json index 328c7e6..5ffca89 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "clean": "rimraf lib", "dev": "babel -w --out-dir lib src", "prebuild": "npm run clean", + "prepare": "npm run build", "build": "babel --out-dir lib src" }, "repository": { diff --git a/src/parse.js b/src/parse.js index 1f9ee50..4672139 100644 --- a/src/parse.js +++ b/src/parse.js @@ -448,6 +448,18 @@ export const extractMessages = (code, opts = {}) => { })) } + if (Array.isArray(opts.overrideContext) && opts.overrideContext.length > 0) { + blocks = blocks.reduce((acc, block) => { + // If we havea msgctxt and it's no the default '' empty context (would be a literal or undefined if a variable) + if ("msgctxt" in block && block.msgctxt !== '') { + return [ + ...acc, + ...opts.overrideContext.map((override) => ({...block, msgctxt: override})) + ]; + } + return [...acc, block]; + }, []); + } return blocks } diff --git a/tests/fixtures/OverrideContext.js b/tests/fixtures/OverrideContext.js new file mode 100644 index 0000000..2602eb3 --- /dev/null +++ b/tests/fixtures/OverrideContext.js @@ -0,0 +1,22 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; +import { GetText, npgettext } from 'gettext-lib'; + +export const Comp = ({ value }) => { + let context = 'foobar'; +return ( +
+ + +
+); +} diff --git a/tests/fixtures/OverrideContext.json b/tests/fixtures/OverrideContext.json new file mode 100644 index 0000000..6e0cf70 --- /dev/null +++ b/tests/fixtures/OverrideContext.json @@ -0,0 +1,26 @@ +[ + { + "msgctxt": "foo", + "msgid": "Translate me", + "comments": { + "reference": [], + "extracted": [] + } + }, + { + "msgctxt": "bar", + "msgid": "Translate me", + "comments": { + "reference": [], + "extracted": [] + } + }, + { + "msgctxt": "", + "msgid": "No context here!", + "comments": { + "reference": [], + "extracted": [] + } + } +] diff --git a/tests/tests.js b/tests/tests.js index afcf39e..05584cf 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -30,7 +30,6 @@ describe('react-gettext-parser', () => { it('should extract a message from jsx', () => { const code = getSource('SingleString.jsx') const messages = extractMessages(code) - const expected = getJson('SingleString.json') expect(messages).to.have.length(1) @@ -553,4 +552,18 @@ describe('react-gettext-parser', () => { expect(messages[0].msgid).to.equal('Pipeline operator works') }) }) + + describe('context override support', () => { + it('should override context', () => { + const code = getSource('OverrideContext.js') + const messages = extractMessages(code, { + overrideContext: ['foo', 'bar'], + }) + const expected = getJson('OverrideContext.json') + expect(messages).to.have.length(3) + expect(messages[0].msgctxt).to.equal(expected[0].msgctxt) + expect(messages[1].msgctxt).to.equal(expected[1].msgctxt) + expect(messages[2].msgctxt).to.equal(expected[2].msgctxt) + }) + }) })