Skip to content

Commit 8b303a6

Browse files
authored
Merge pull request #264 from BorisTB/master
Support keyPrefix
2 parents 5eb8f8b + 866d257 commit 8b303a6

File tree

12 files changed

+107
-3
lines changed

12 files changed

+107
-3
lines changed

src/extractors/getFixedTFunction.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ export default function extractGetFixedTFunction(
6767
const tBinding = id.scope.bindings[id.node.name];
6868
if (!tBinding) return [];
6969

70+
const keyPrefixArgument = path.get('arguments')[2];
71+
const keyPrefix: string | null = getFirstOrNull(
72+
evaluateIfConfident(keyPrefixArgument),
73+
);
74+
7075
let keys = Array<ExtractedKey>();
7176
for (const reference of tBinding.referencePaths) {
7277
if (
@@ -85,6 +90,7 @@ export default function extractGetFixedTFunction(
8590
...k,
8691
parsedOptions: {
8792
...k.parsedOptions,
93+
keyPrefix: k.parsedOptions.keyPrefix || keyPrefix,
8894
ns: k.parsedOptions.ns || ns,
8995
},
9096
})),

src/extractors/tFunction.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ function parseTCallOptions(
5050
contexts: false,
5151
hasCount: false,
5252
ns: null,
53+
keyPrefix: null,
5354
defaultValue: null,
5455
};
5556

@@ -76,6 +77,12 @@ function parseTCallOptions(
7677
const defaultValueNodeValue = defaultValueNode.get('value');
7778
res.defaultValue = evaluateIfConfident(defaultValueNodeValue);
7879
}
80+
81+
const keyPrefixNode = findKeyInObjectExpression(path, 'keyPrefix');
82+
if (keyPrefixNode !== null && keyPrefixNode.isObjectProperty()) {
83+
const keyPrefixNodeValue = keyPrefixNode.get('value');
84+
res.keyPrefix = evaluateIfConfident(keyPrefixNodeValue);
85+
}
7986
}
8087

8188
return res;

src/extractors/transComponent.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ function parseTransComponentOptions(
5050
const res: ExtractedKey['parsedOptions'] = {
5151
contexts: false,
5252
hasCount: false,
53+
keyPrefix: null,
5354
ns: null,
5455
defaultValue: null,
5556
};

src/extractors/useTranslationHook.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ export default function extractUseTranslationHook(
5959
const tBinding = id.scope.bindings['t'];
6060
if (!tBinding) return [];
6161

62+
let keyPrefix: string | null = null;
63+
64+
const optionsArgument = path.get('arguments')[1];
65+
const options = getFirstOrNull(evaluateIfConfident(optionsArgument));
66+
67+
if (options) {
68+
keyPrefix = options.keyPrefix || keyPrefix;
69+
}
70+
6271
let keys = Array<ExtractedKey>();
6372
for (const reference of tBinding.referencePaths) {
6473
if (
@@ -77,6 +86,7 @@ export default function extractUseTranslationHook(
7786
...k,
7887
parsedOptions: {
7988
...k.parsedOptions,
89+
keyPrefix: k.parsedOptions.keyPrefix || keyPrefix,
8090
ns: k.parsedOptions.ns || ns,
8191
},
8292
})),

src/keys.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ interface I18NextParsedOptions {
1010
contexts: string[] | boolean;
1111
hasCount: boolean;
1212
ns: string | null;
13+
keyPrefix: string | null;
1314
defaultValue: string | null;
1415
}
1516

@@ -49,6 +50,13 @@ export interface TranslationKey extends ExtractedKey {
4950
function parseExtractedKey(key: ExtractedKey, config: Config): TranslationKey {
5051
let cleanKey = key.key;
5152

53+
const keyPrefix = key.parsedOptions.keyPrefix;
54+
if (keyPrefix) {
55+
// Imitate behavior of i18next and just connect prefix with key before any other action
56+
const keySeparator = config.keySeparator || '.';
57+
cleanKey = `${keyPrefix}${keySeparator}${cleanKey}`;
58+
}
59+
5260
let ns: string = key.parsedOptions.ns || config.defaultNS;
5361
if (config.nsSeparator) {
5462
const nsSeparatorPos = cleanKey.indexOf(config.nsSeparator);
@@ -60,9 +68,10 @@ function parseExtractedKey(key: ExtractedKey, config: Config): TranslationKey {
6068
}
6169

6270
let keyPath = Array<string>();
71+
6372
if (config.keySeparator) {
6473
const fullPath = cleanKey.split(config.keySeparator);
65-
keyPath = fullPath.slice(0, fullPath.length - 1);
74+
keyPath = [...keyPath, ...fullPath.slice(0, fullPath.length - 1)];
6675
cleanKey = fullPath[fullPath.length - 1];
6776
}
6877

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import i18next from "i18next";
2+
3+
export function anyJSFunction1() {
4+
const t = i18next.getFixedT(null, 'ns0', 'deep0');
5+
t('key0');
6+
}
7+
8+
export function anyJSFunction2() {
9+
const t = i18next.getFixedT(null, 'ns1', 'deep1.deep2');
10+
11+
t('key1');
12+
}
13+
14+
export function anyJSFunction3() {
15+
const t = i18next.getFixedT(null, 'ns2', 'deep3.deep4');
16+
17+
t('key2.key3');
18+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"description": "test keyPrefix usage of getFixedT TFunction",
3+
"pluginOptions": {},
4+
"expectValues": [
5+
[{"deep0": { "key0": "" }}, {"ns": "ns0"}],
6+
[{"deep1": { "deep2": { "key1": "" }}}, {"ns": "ns1"}],
7+
[{"deep3": { "deep4": { "key2": { "key3": "" } }}}, {"ns": "ns2"}]
8+
]
9+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { useTranslation } from 'react-i18next';
2+
3+
export function MyComponent1() {
4+
const [t] = useTranslation('ns0', { keyPrefix: 'deep0' });
5+
return <p>{t('key0')}{t('key1')}</p>
6+
}
7+
8+
export function MyComponent2() {
9+
const [t] = useTranslation('ns1', { keyPrefix: 'deep1.deep2' });
10+
return <p>{t('key2')}{t('key3')}</p>
11+
}
12+
13+
export function MyComponent3() {
14+
const [t] = useTranslation('ns2', { keyPrefix: 'deep3.deep4' });
15+
return <p>{t('key4.key5')}{t('key4.key6')}</p>
16+
}
17+
18+
export function MyComponent4() {
19+
const [t] = useTranslation('ns3', { keyPrefix: 'deep5.deep6' });
20+
return <p>{t('key7.key8')}{t('key9.key10')}</p>
21+
}
22+
23+
export function MyComponent5() {
24+
const [t] = useTranslation('ns4', { keyPrefix: 'deep7.deep8' });
25+
return <p>{t('ns5:key11')}</p>
26+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"description": "test keyPrefix extraction of useTranslation hook",
3+
"pluginOptions": {},
4+
"expectValues": [
5+
[{ "deep0": {"key0": "", "key1": ""}}, {"ns": "ns0"}],
6+
[{ "deep1": {"deep2": {"key2": "", "key3": ""}}}, {"ns": "ns1"}],
7+
[{ "deep3": {"deep4": {"key4": { "key5": "", "key6": "" }}}}, {"ns": "ns2"}],
8+
[{ "deep5": {"deep6": {"key7": { "key8": "" }, "key9": {"key10": ""}}}}, {"ns": "ns3"}],
9+
[{ "key11": ""}, {"ns": "deep7.deep8.ns5"}]
10+
]
11+
}

tests/__fixtures__/testUseTranslationHook/simple.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@ const MyComponent2 = () => {
1818
return <p>{t('key2')}</p>
1919
}
2020

21-
export function MyComponent3() {
21+
const MyComponent3 = () => {
22+
const { t, i18n } = useTranslation();
23+
return <p>{t('key3.key4')}</p>
24+
}
25+
26+
export function MyComponent4() {
2227
const {i18n} = useTranslation();
2328
return <p>Shouldn't crash</p>
2429
}
2530

26-
export function MyComponent4() {
31+
export function MyComponent5() {
2732
const { t } = ReactI18Next.useTranslation();
2833
t('from wildcard import');
2934
}

tests/__fixtures__/testUseTranslationHook/simple.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"key0": "",
66
"key1": "",
77
"key2": "",
8+
"key3": { "key4": "" },
89
"from wildcard import": ""
910
}
1011
}

tests/helpers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export function createTranslationKey(
1313
parsedOptions: {
1414
contexts: false,
1515
hasCount: false,
16+
keyPrefix: null,
1617
ns: null,
1718
defaultValue: null,
1819
},

0 commit comments

Comments
 (0)