Skip to content

Commit 652b827

Browse files
feat: add i18next-shopify framework (#970)
* Return first available counting value if nested * Add extraction support to react-i18next framework This commit adds the `supportAutoExtraction` array of supported formats and the `detectHardStrings` method from `GeneralFramework` to enable hard-coded string extraction for react-i18next framework, without needing the "general" framework to be enabled/loaded in the `.vscode/settings.json` file. * Add i18next-shopify framework This commit adds the i18next-shopify framework to the list of supported frameworks. It is an extension of the React i18next framework, with some configuration changes. Also add i18next-shopify example app, including a pluralization example. * Add support for Go to Definition of a translation key * Fixes usage report for non-missing derived keys Derived keys (e.g., such as plurals) were being miscategorised as missing in the usage report. This commit checks if keys derived from those found in the missing list (keys that are in use but considered "not defined") are included in the list of idle keys (keys defined but not considered in use), indicating that they are indeed defined and in use. Fixes #953 * Fixes Current File Panel report of not found keys Derived keys (e.g., such as plurals) are being miscategorised as not found in the Current File Panel report. This commit checks if any existing key paths match derived keys paths, and if so, includes them in the list of in use key paths and removed from the "not found" list. Fixes #959 * Chore: fix spellings in code base --------- Co-authored-by: Kevin O'Sullivan <[email protected]>
1 parent 43df97d commit 652b827

File tree

35 files changed

+585
-42
lines changed

35 files changed

+585
-42
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"i18n-ally.localesPaths": "public/locales",
3+
"i18n-ally.enabledFrameworks": ["i18next-shopify"],
4+
"i18n-ally.namespace": true,
5+
"i18n-ally.pathMatcher": "{locale}/{namespaces}.json",
6+
"i18n-ally.keystyle": "nested",
7+
"i18n-ally.keysInUse": ["description.part2_whatever"]
8+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "react_usinghooks",
3+
"version": "0.1.0",
4+
"private": true,
5+
"dependencies": {
6+
"i18next": "20.3.0",
7+
"i18next-browser-languagedetector": "6.1.1",
8+
"i18next-xhr-backend": "3.2.2",
9+
"react": "17.0.2",
10+
"react-dom": "17.0.2",
11+
"react-i18next": "11.9.0",
12+
"@shopify/i18next-shopify": "0.2.3",
13+
"react-scripts": "4.0.3"
14+
},
15+
"scripts": {
16+
"start": "react-scripts start",
17+
"build": "react-scripts build",
18+
"test": "react-scripts test --env=jsdom",
19+
"eject": "react-scripts eject"
20+
}
21+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6+
<meta name="theme-color" content="#000000">
7+
<title>React App</title>
8+
</head>
9+
<body>
10+
<noscript>
11+
You need to enable JavaScript to run this app.
12+
</noscript>
13+
<div id="root"></div>
14+
</body>
15+
</html>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"title": "Zuhause"
3+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"title": "Willkommen zu react und react-i18next",
3+
"description": {
4+
"part1": "Um loszulegen, ändere <1>src/App(DE).js</1> speicheren und neuladen.",
5+
"part2": "Ändere die Sprachen zwischen deutsch und englisch mit Hilfe der beiden Schalter."
6+
},
7+
"count": {
8+
"one": "{{count}} Satz übersetzt!",
9+
"other": "{{count}} Sätze übersetzt!"
10+
}
11+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"title": "Home"
3+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"title": "hello",
3+
"description": {
4+
"part1": "To get started, edit <1>src/App.js</1> and save to reload.",
5+
"part2": "Switch language between english and german using buttons above."
6+
},
7+
"titlew": "ok",
8+
"foo": {
9+
"bar": "foobar"
10+
},
11+
"count": {
12+
"one": "{{count}} phrase translated!",
13+
"other": "{{count}} phrases translated!"
14+
}
15+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.App {
2+
text-align: center;
3+
}
4+
5+
.App-header {
6+
background-color: #222;
7+
height: 100px;
8+
padding: 20px;
9+
color: white;
10+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/* eslint-disable no-undef */
2+
/* eslint-disable @typescript-eslint/no-unused-vars */
3+
/* eslint-disable no-unused-vars */
4+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
5+
import React, { Component } from "react";
6+
import { useTranslation, withTranslation, Trans } from "react-i18next";
7+
import "./App.css";
8+
9+
// use hoc for class based components
10+
class LegacyWelcomeClass extends Component {
11+
render() {
12+
const { t } = this.props;
13+
return (
14+
<div>
15+
<h2>Plain Text</h2>
16+
<h2>{t("translation.title")}</h2>
17+
</div>
18+
);
19+
}
20+
}
21+
const Welcome = withTranslation()(LegacyWelcomeClass);
22+
23+
// Component using the Trans component
24+
function MyComponent() {
25+
return (
26+
<Trans i18nKey="translation:description.part1">
27+
To get started, edit <code>src/App.js</code> and save to reload.
28+
</Trans>
29+
);
30+
}
31+
32+
// page uses the hook
33+
function Page() {
34+
const { t, i18n } = useTranslation();
35+
36+
const changeLanguage = lng => {
37+
i18n.changeLanguage(lng);
38+
};
39+
40+
return (
41+
<div className="App">
42+
<div className="App-header">
43+
<Welcome />
44+
<button onClick={() => changeLanguage("de")}>de</button>
45+
<button onClick={() => changeLanguage("en")}>en</button>
46+
</div>
47+
<div className="App-intro">
48+
<MyComponent />
49+
</div>
50+
<div>{t("translation.description.part2")}</div>
51+
{/* plain <Trans>, #423 */}
52+
<Trans i18nKey="translation.description.part2">Fallback text</Trans>
53+
<p>{t("translation.count", { count: 1 })}</p>
54+
</div>
55+
);
56+
}
57+
58+
// hook with scope
59+
function Page2() {
60+
const { t } = useTranslation(["translation.foo"]);
61+
62+
// inside default namespace ("foo.bar")
63+
t("bar");
64+
65+
// explicit namespace
66+
t("pages.home:title");
67+
t("pages/home:title");
68+
}
69+
70+
// hook with another scope
71+
function Page3() {
72+
const { t } = useTranslation("pages/home");
73+
74+
t("title");
75+
76+
// explicit namespace
77+
t("translation:title");
78+
}
79+
80+
// hook with scope in options
81+
function Page4() {
82+
const { t } = useTranslation("pages/home");
83+
84+
t("title");
85+
86+
// explicit namespace
87+
t("title", { ns: "translation" });
88+
}
89+
90+
// component with scope in props
91+
function Page5() {
92+
const { t } = useTranslation("pages/home");
93+
94+
return (
95+
<div className="App">
96+
<Trans t={t} i18nKey="title"></Trans>
97+
{/* explicit namespace */}
98+
<Trans t={t} i18nKey="title" ns="translation"></Trans>
99+
</div>
100+
);
101+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2+
import React from "react";
3+
import i18n from "i18next";
4+
import Backend from "i18next-xhr-backend";
5+
import LanguageDetector from "i18next-browser-languagedetector";
6+
import { initReactI18next } from "react-i18next";
7+
import ShopifyFormat from "@shopify/i18next-shopify";
8+
9+
i18n
10+
// load translation using xhr -> see /public/locales
11+
// learn more: https://github.com/i18next/i18next-xhr-backend
12+
.use(Backend)
13+
// detect user language
14+
// learn more: https://github.com/i18next/i18next-browser-languageDetector
15+
.use(LanguageDetector)
16+
// pass the i18n instance to react-i18next.
17+
.use(initReactI18next)
18+
// configure with Shopify-specific formats
19+
.use(ShopifyFormat)
20+
// init i18next
21+
// for all options read: https://www.i18next.com/overview/configuration-options
22+
.init({
23+
fallbackLng: "en",
24+
debug: true,
25+
26+
interpolation: {
27+
escapeValue: false // not needed for react as it escapes by default
28+
}
29+
});
30+
31+
export default i18n;

0 commit comments

Comments
 (0)