Skip to content

Commit 41fa1ca

Browse files
authored
Merge pull request #1 from darrenlucas/load-translations
Allow loading translation messages from mo file for current locale
2 parents bdce51a + 46a33a5 commit 41fa1ca

File tree

10 files changed

+101
-11
lines changed

10 files changed

+101
-11
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ object to child components. Wrap your component in a Localizer as follows:
2323
import App from "app"
2424

2525
render(
26-
<Localizer locale="cy">
26+
<Localizer locale="cy" localeDir="./locale">
2727
<App />
2828
</Localizer>
2929
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-g11n",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"description": "Globalization for react components using gettext",
55
"main": "./lib/index.js",
66
"files": [

src/localizer.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import translatorFactory from './translator-factory';
44
class Localizer extends Component {
55

66
getChildContext() {
7-
const { locale } = this.props;
7+
const { locale, localeDir } = this.props;
88
return {
99
locale: locale,
10-
translator: translatorFactory(locale)
10+
translator: translatorFactory(locale, { localeDir: localeDir })
1111
};
1212
}
1313

@@ -20,6 +20,11 @@ class Localizer extends Component {
2020
Localizer.propTypes = {
2121
children: PropTypes.node,
2222
locale: PropTypes.string.isRequired,
23+
localeDir: PropTypes.string
24+
};
25+
26+
Localizer.defaultProps = {
27+
localeDir: 'locale'
2328
};
2429

2530
Localizer.childContextTypes = {

src/translator-factory.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1+
import path from 'path';
12
import fs from 'fs';
23
import gettextParser from 'gettext-parser';
34
import Translator from './translator';
45

5-
const translatorFactory = (locale) => {
6+
const translatorFactory = (locale, { localeDir = './locale' } = {}) => {
67

7-
// TODO: Translation file loading
8-
// Always load from localeDir/<locale>/LC_MESSAGES/messages.mo
9-
//const filePath = path.resolve(localeDir, locale, 'LC_MESSAGES', 'messages.mo');
10-
//const moFile = fs.readFileSync(moFile, 'utf-8');
11-
//const { translations } = moFile;
8+
var translations = {};
129

13-
const translator = new Translator(locale);
10+
// TODO: Currently only a domain of 'messages' is supported
11+
const filePath = path.resolve(localeDir, locale, 'LC_MESSAGES', 'messages.mo');
12+
13+
if (fs.existsSync(filePath)) {
14+
const moFile = fs.readFileSync(filePath);
15+
var { translations } = gettextParser.mo.parse(moFile, 'utf-8');
16+
}
17+
18+
const translator = new Translator(locale, translations);
1419

1520
return translator;
1621

test/fixtures/locale/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Test Locales
2+
============
3+
4+
This directory contains locales used for unit testing.
5+
6+
To update locales from the pot file run the following:
7+
8+
msgmerge --update fr/LC_MESSAGES/messages.po messages.pot
9+
10+
To compile .mo files:
11+
12+
msgfmt fr/LC_MESSAGES/messages.po -o fr/LC_MESSAGES/messages.mo
451 Bytes
Binary file not shown.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
msgid ""
2+
msgstr ""
3+
"Project-Id-Version: react-g 11n\n"
4+
"Report-Msgid-Bugs-To: \n"
5+
"POT-Creation-Date: 2017-01-15 20:51+0000\n"
6+
"PO-Revision-Date: 2017-01-27 14:35+0000\n"
7+
"Last-Translator: Darren Lucas <[email protected]>\n"
8+
"Language-Team: French\n"
9+
"Language: fr\n"
10+
"MIME-Version: 1.0\n"
11+
"Content-Type: text/plain; charset=UTF-8\n"
12+
"Content-Transfer-Encoding: 8bit\n"
13+
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
14+
15+
msgid "hello"
16+
msgstr "bonjour"

test/fixtures/locale/messages.pot

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
msgid ""
2+
msgstr ""
3+
"Project-Id-Version: PACKAGE VERSION\n"
4+
"Language-Team: LANGUAGE <[email protected]>\n"
5+
"Report-Msgid-Bugs-To: \n"
6+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
7+
"Language: \n"
8+
"MIME-Version: 1.0\n"
9+
"Content-Type: text/plain; charset=utf-8\n"
10+
"Content-Transfer-Encoding: 8bit\n"
11+
"POT-Creation-Date: 2017-01-15 20:51+0000\n"
12+
13+
msgid "hello"
14+
msgstr ""

test/localizer.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,26 @@ test('Localizer', () => {
2424
);
2525

2626
});
27+
28+
test('Localizer with localeDir', () => {
29+
30+
class DummyComponent extends Component {
31+
render() {
32+
expect(this.context.locale).toBe('fr');
33+
expect(this.context.translator.translate('hello')).toBe('bonjour');
34+
return null
35+
}
36+
}
37+
38+
DummyComponent.contextTypes = {
39+
locale: PropTypes.string,
40+
translator: PropTypes.object
41+
};
42+
43+
renderer.create(
44+
<Localizer locale='fr' localeDir='./test/fixtures/locale'>
45+
<DummyComponent />
46+
</Localizer>
47+
);
48+
49+
});

test/translator-factory.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import translatorFactory from '../src/translator-factory';
2+
3+
const options = {
4+
localeDir: './test/fixtures/locale'
5+
}
6+
7+
test('translatorFactory', () => {
8+
const translator = translatorFactory('fr', options);
9+
expect(translator.translate('hello')).toBe('bonjour');
10+
});
11+
12+
test('translatorFactory with missing locale', () => {
13+
const translator = translatorFactory('es', options);
14+
expect(translator.translate('hello')).toBe('hello');
15+
});

0 commit comments

Comments
 (0)