@absolutesight/react-gettext 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -15
- package/package.json +4 -7
package/README.md
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
# @absolutesight/react-gettext
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
> [!WARNING]
|
|
4
|
+
> ### ⚠️ DEPRECATION NOTICE: This package is obsolete and no longer maintained
|
|
5
|
+
>
|
|
6
|
+
> **`@absolutesight/react-gettext` has been replaced by [**`@absolutesight/gettext`**](https://www.npmjs.com/package/@absolutesight/gettext).**
|
|
7
|
+
>
|
|
8
|
+
> Please migrate to the new package:
|
|
9
|
+
>
|
|
10
|
+
> ```bash
|
|
11
|
+
> npm install @absolutesight/gettext
|
|
12
|
+
> ```
|
|
13
|
+
>
|
|
14
|
+
> #### Why switch to [`@absolutesight/gettext`](https://www.npmjs.com/package/@absolutesight/gettext)?
|
|
15
|
+
> - 🌐 **Universal Framework Support**: While this old library only supported React.js and Next.js, the new package works across **all JavaScript frameworks and environments** — React, Next.js (App & Pages Router), Vue, Svelte, Node.js, and vanilla JavaScript.
|
|
16
|
+
> - ⚡ **High Performance & Zero Dependencies**: Lightweight, tree-shakeable, and built with modern TypeScript.
|
|
17
|
+
> - 🧩 **Full WordPress Parity**: Complete implementation of WordPress-standard gettext functions (`__()`, `_n()`, `_x()`, `_nx()`, `_noop()`, `sprintf()`), PO/MO/JSON file parsing, and JSX interpolation.
|
|
18
|
+
> - 🔒 **Safe Plural Evaluation**: Secure AST-based plural evaluator replacing insecure `eval()`.
|
|
19
|
+
>
|
|
20
|
+
> 👉 **Documentation & Migration Guide:** [https://www.npmjs.com/package/@absolutesight/gettext](https://www.npmjs.com/package/@absolutesight/gettext)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Legacy Overview (Archived)
|
|
6
25
|
|
|
7
26
|
> **Note:** This library requires **React 16.3 or later**
|
|
8
27
|
|
|
@@ -22,12 +41,12 @@ Let's take a closer look at each step. First of all, you to create translation c
|
|
|
22
41
|
|
|
23
42
|
The translation catalog is an object that contains key/value pairs where keys are original singular messages and values are translations. If you have a message that can have plural forms, the value for it should be an array with translations where each translation corresponds to appropriate plural form. Finally, if you want to use a context with your messages, then it should be prepended to the message itself and separated by using `\u0004` (end of transition) character. Here is an example:
|
|
24
43
|
|
|
25
|
-
```
|
|
44
|
+
```json
|
|
26
45
|
{
|
|
27
|
-
"Hello world!": "¡Hola Mundo!",
|
|
28
|
-
"article": ["artículo", "artículos"],
|
|
29
|
-
"Logo link\u0004Homepage": "Página principal",
|
|
30
|
-
"Search results count\u0004article": ["artículo", "artículos"]
|
|
46
|
+
"Hello world!": "¡Hola Mundo!",
|
|
47
|
+
"article": ["artículo", "artículos"],
|
|
48
|
+
"Logo link\u0004Homepage": "Página principal",
|
|
49
|
+
"Search results count\u0004article": ["artículo", "artículos"]
|
|
31
50
|
}
|
|
32
51
|
```
|
|
33
52
|
|
|
@@ -49,7 +68,7 @@ class MyApp extends Component {
|
|
|
49
68
|
|
|
50
69
|
constructor(props) {
|
|
51
70
|
super(props);
|
|
52
|
-
this.state = { textDomain: buildTextDomain(...) };
|
|
71
|
+
this.state = { textDomain: buildTextDomain("...") };
|
|
53
72
|
}
|
|
54
73
|
|
|
55
74
|
render() {
|
|
@@ -57,8 +76,7 @@ class MyApp extends Component {
|
|
|
57
76
|
<div>
|
|
58
77
|
<TextDomainContext.Provider value={this.state.textDomain}>
|
|
59
78
|
<ComponentA />
|
|
60
|
-
|
|
61
|
-
</TextDomainContext>
|
|
79
|
+
</TextDomainContext.Provider>
|
|
62
80
|
</div>
|
|
63
81
|
);
|
|
64
82
|
}
|
|
@@ -306,7 +324,7 @@ As an alternative you can pass translations and plural form as properties to hig
|
|
|
306
324
|
function getTranslations() {
|
|
307
325
|
return {
|
|
308
326
|
'Some text': 'Some translated text',
|
|
309
|
-
...
|
|
327
|
+
// ...
|
|
310
328
|
};
|
|
311
329
|
}
|
|
312
330
|
|
|
@@ -316,9 +334,9 @@ function getPluralForms(n) {
|
|
|
316
334
|
|
|
317
335
|
const HOC = withGettext()(App);
|
|
318
336
|
|
|
319
|
-
...
|
|
337
|
+
// ...
|
|
320
338
|
|
|
321
|
-
ReactDOM.render(<HOC translations={getTranslations} plural={getPluralForms}>...</HOC>, ...);
|
|
339
|
+
ReactDOM.render(<HOC translations={getTranslations} plural={getPluralForms}>...</HOC>, /* ... */);
|
|
322
340
|
```
|
|
323
341
|
|
|
324
342
|
One more alternative is to not create HOC, but use TextDomain component directly. You can import it using `import { Textdomain } from '@absolutesight/react-gettext'` and use it as a regular component which will provide context functions to translate your messages. Just don't forget to pass `translations` and `plural` props to this component when you render it.
|
|
@@ -352,8 +370,56 @@ msgstr ""
|
|
|
352
370
|
|
|
353
371
|
If you prefer using npm scripts, then you can add the following command to your `package.json` file to extract static copy and generate POT file using CLI commands. Make sure, you have correct `project` and `output` paths.
|
|
354
372
|
|
|
373
|
+
```json
|
|
374
|
+
{
|
|
375
|
+
"scripts": {
|
|
376
|
+
"gettext:convert": "gettextjs --json ./",
|
|
377
|
+
"gettext:compile": "find ./languages/LC_MESSAGES -name \\*.po -execdir sh -c 'msgfmt \"$0\" -o `basename $0 .po`.mo' '{}' \\;",
|
|
378
|
+
"gettext": "npm run gettext:compile && npm run gettext:convert",
|
|
379
|
+
"gettext:extract": "find /path/to/project -name \"*.js\" -not -path './node_modules/*' -not -path './node_modules/*' | xargs xgettext --from-code=UTF-8 --language=JavaScript --keyword=gettext --keyword=gettext_next --keyword=ngettext:1,2 --keyword=xgettext:1,2c --keyword=nxgettext:1,2,4c --output=./location/top/pot/file/example.pot --sort-by-file --package-name=\"My Project Name\" --package-version=\"0.1.0\""
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## Requirements
|
|
385
|
+
### For Ubuntu
|
|
386
|
+
```
|
|
387
|
+
sudo apt update && sudo apt install gettext -y
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### For macOS (using Homebrew):
|
|
391
|
+
```
|
|
392
|
+
brew install gettext
|
|
393
|
+
brew link --force gettext
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### For Arch Linux:
|
|
397
|
+
```
|
|
398
|
+
sudo pacman -S gettext
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### For Windows (using Chocolatey):
|
|
355
402
|
```
|
|
356
|
-
|
|
403
|
+
choco install gettext
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
# Information Related to next.js
|
|
407
|
+
I have added the next.js support in my code. For this you need to use `gettext_next` function instead of `gettext`.
|
|
408
|
+
If you see that some text is not translating properly. You can define variable with `gettext_next` function and then use that variable in your JSX.
|
|
409
|
+
|
|
410
|
+
```javascript
|
|
411
|
+
import * as ProtoTypes from "prop-types";
|
|
412
|
+
import {GetText} from "@/components";
|
|
413
|
+
|
|
414
|
+
export const gettext_next = (text) => {
|
|
415
|
+
text = text.replace("%%", "%");
|
|
416
|
+
return <GetText>{text}</GetText>;
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
gettext_next.protoTypes = {
|
|
420
|
+
text: ProtoTypes.string
|
|
421
|
+
};
|
|
422
|
+
|
|
357
423
|
```
|
|
358
424
|
|
|
359
425
|
## Contribute
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"bugs": {
|
|
8
8
|
"url": "https://absolutesight.com"
|
|
9
9
|
},
|
|
10
|
-
"version": "1.0.
|
|
10
|
+
"version": "1.0.7",
|
|
11
11
|
"main": "src/index.js",
|
|
12
12
|
"files": [
|
|
13
13
|
"*.md",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"build:umd": "webpack --output-filename=react-gettext.js",
|
|
34
34
|
"build:umd:min": "NODE_ENV=production webpack --output-filename=react-gettext.min.js",
|
|
35
35
|
"build:umd:min:win": "set NODE_ENV=production webpack --output-filename=react-gettext.min.js",
|
|
36
|
-
"test": "BABEL_ENV=test jest",
|
|
36
|
+
"test": "BABEL_ENV=test jest --passWithNoTests",
|
|
37
37
|
"prepublish": "npm run build",
|
|
38
38
|
"lint": "eslint src --fix --max-warnings=0"
|
|
39
39
|
},
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"jest-enzyme": "^7.1.2",
|
|
58
58
|
"lodash": "^4.17.21",
|
|
59
59
|
"prop-types": "^15.8.1",
|
|
60
|
-
"react": "^
|
|
60
|
+
"react": "^19.0.0",
|
|
61
61
|
"react-dom": "^18.2.0",
|
|
62
62
|
"react-test-renderer": "^18.2.0",
|
|
63
63
|
"webpack": "^5.90.3",
|
|
@@ -69,12 +69,9 @@
|
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"hoist-non-react-statics": "^1.2.0 || ^2.0.0-0 || ^3.0.0-0",
|
|
71
71
|
"prop-types": "^15.0.0-0 || ^16.0.0-0",
|
|
72
|
-
"react": "^
|
|
72
|
+
"react": "^19.0.0"
|
|
73
73
|
},
|
|
74
74
|
"jest": {
|
|
75
|
-
"setupFilesAfterEnv": [
|
|
76
|
-
"<rootDir>/__tests__/__setup.js"
|
|
77
|
-
],
|
|
78
75
|
"testMatch": [
|
|
79
76
|
"<rootDir>/__tests__/**/[^_]*.js"
|
|
80
77
|
],
|