From d8991fb3e11d716f614c0e9f0a585adca7791e80 Mon Sep 17 00:00:00 2001 From: Mark Steele Date: Thu, 19 Nov 2020 18:29:29 -0500 Subject: [PATCH 1/4] context override --- src/parse.js | 9 +++++++++ tests/fixtures/OverrideContext.json | 18 ++++++++++++++++++ tests/tests.js | 13 +++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 tests/fixtures/OverrideContext.json diff --git a/src/parse.js b/src/parse.js index 1f9ee50..59c1437 100644 --- a/src/parse.js +++ b/src/parse.js @@ -448,6 +448,15 @@ export const extractMessages = (code, opts = {}) => { })) } + if (Array.isArray(opts.overrideContext) && opts.overrideContext.length > 0) { + blocks = opts.overrideContext.reduce((acc, override) => { + return [...acc, ...blocks.map(block => ({ + ...block, + msgctxt: override + }))] + }, []) + } + return blocks } diff --git a/tests/fixtures/OverrideContext.json b/tests/fixtures/OverrideContext.json new file mode 100644 index 0000000..620bd19 --- /dev/null +++ b/tests/fixtures/OverrideContext.json @@ -0,0 +1,18 @@ +[ + { + "msgctxt": "foo", + "msgid": "Translate me", + "comments": { + "reference": [], + "extracted": [] + } + }, + { + "msgctxt": "bar", + "msgid": "Translate me", + "comments": { + "reference": [], + "extracted": [] + } + } +] diff --git a/tests/tests.js b/tests/tests.js index afcf39e..66fa433 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -553,4 +553,17 @@ describe('react-gettext-parser', () => { expect(messages[0].msgid).to.equal('Pipeline operator works') }) }) + + describe('context override support', () => { + it('should override context', () => { + const code = getSource('SingleString.jsx') + const messages = extractMessages(code, { + overrideContext: ['foo', 'bar'], + }) + const expected = getJson('OverrideContext.json') + expect(messages).to.have.length(2) + expect(messages[0].msgctxt).to.equal(expected[0].msgctxt) + expect(messages[1].msgctxt).to.equal(expected[1].msgctxt) + }) + }) }) From 5be0c1485fe1591f2f6a27553d77057b6dc12f8c Mon Sep 17 00:00:00 2001 From: Mark Steele Date: Thu, 19 Nov 2020 18:55:20 -0500 Subject: [PATCH 2/4] updated tests, doc --- README.md | 41 +++++++++++++++++++++++++++++++ tests/fixtures/OverrideContext.js | 15 +++++++++++ tests/tests.js | 3 +-- 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/OverrideContext.js 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/tests/fixtures/OverrideContext.js b/tests/fixtures/OverrideContext.js new file mode 100644 index 0000000..515e667 --- /dev/null +++ b/tests/fixtures/OverrideContext.js @@ -0,0 +1,15 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; +import { GetText, npgettext } from 'gettext-lib'; + +export const Comp = ({ value }) => +
+ + +
; diff --git a/tests/tests.js b/tests/tests.js index 66fa433..92e3f62 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) @@ -556,7 +555,7 @@ describe('react-gettext-parser', () => { describe('context override support', () => { it('should override context', () => { - const code = getSource('SingleString.jsx') + const code = getSource('OverrideContext.js') const messages = extractMessages(code, { overrideContext: ['foo', 'bar'], }) From 488bdf6b75f2eba46b30fa08a5008416601bac1f Mon Sep 17 00:00:00 2001 From: Mark Steele Date: Thu, 19 Nov 2020 21:54:03 -0500 Subject: [PATCH 3/4] adding prepare --- package.json | 1 + 1 file changed, 1 insertion(+) 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": { From b5887b4cd12e56d86d0afd349d93e9172eebe5f5 Mon Sep 17 00:00:00 2001 From: Mark Steele Date: Mon, 23 Nov 2020 13:23:01 -0500 Subject: [PATCH 4/4] better default context support --- src/parse.js | 17 ++++++++++------- tests/fixtures/OverrideContext.js | 29 ++++++++++++++++++----------- tests/fixtures/OverrideContext.json | 8 ++++++++ tests/tests.js | 3 ++- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/parse.js b/src/parse.js index 59c1437..4672139 100644 --- a/src/parse.js +++ b/src/parse.js @@ -449,14 +449,17 @@ export const extractMessages = (code, opts = {}) => { } if (Array.isArray(opts.overrideContext) && opts.overrideContext.length > 0) { - blocks = opts.overrideContext.reduce((acc, override) => { - return [...acc, ...blocks.map(block => ({ - ...block, - msgctxt: override - }))] - }, []) + 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 index 515e667..2602eb3 100644 --- a/tests/fixtures/OverrideContext.js +++ b/tests/fixtures/OverrideContext.js @@ -2,14 +2,21 @@ import React from 'react'; import { GetText, npgettext } from 'gettext-lib'; -export const Comp = ({ value }) => -
- - -
; +export const Comp = ({ value }) => { + let context = 'foobar'; +return ( +
+ + +
+); +} diff --git a/tests/fixtures/OverrideContext.json b/tests/fixtures/OverrideContext.json index 620bd19..6e0cf70 100644 --- a/tests/fixtures/OverrideContext.json +++ b/tests/fixtures/OverrideContext.json @@ -14,5 +14,13 @@ "reference": [], "extracted": [] } + }, + { + "msgctxt": "", + "msgid": "No context here!", + "comments": { + "reference": [], + "extracted": [] + } } ] diff --git a/tests/tests.js b/tests/tests.js index 92e3f62..05584cf 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -560,9 +560,10 @@ describe('react-gettext-parser', () => { overrideContext: ['foo', 'bar'], }) const expected = getJson('OverrideContext.json') - expect(messages).to.have.length(2) + 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) }) }) })