diff --git a/README.md b/README.md index 366f138..5f4ce66 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ object to child components. Wrap your component in a Localizer as follows: import App from "app" render( - + } diff --git a/package.json b/package.json index 4348c5f..de506d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-g11n", - "version": "0.1.0", + "version": "0.2.0", "description": "Globalization for react components using gettext", "main": "./lib/index.js", "files": [ diff --git a/src/localizer.js b/src/localizer.js index 8c20141..1416f63 100644 --- a/src/localizer.js +++ b/src/localizer.js @@ -4,10 +4,10 @@ import translatorFactory from './translator-factory'; class Localizer extends Component { getChildContext() { - const { locale } = this.props; + const { locale, localeDir } = this.props; return { locale: locale, - translator: translatorFactory(locale) + translator: translatorFactory(locale, { localeDir: localeDir }) }; } @@ -20,6 +20,11 @@ class Localizer extends Component { Localizer.propTypes = { children: PropTypes.node, locale: PropTypes.string.isRequired, + localeDir: PropTypes.string +}; + +Localizer.defaultProps = { + localeDir: 'locale' }; Localizer.childContextTypes = { diff --git a/src/translator-factory.js b/src/translator-factory.js index 3f107e1..33a6df5 100644 --- a/src/translator-factory.js +++ b/src/translator-factory.js @@ -1,16 +1,21 @@ +import path from 'path'; import fs from 'fs'; import gettextParser from 'gettext-parser'; import Translator from './translator'; -const translatorFactory = (locale) => { +const translatorFactory = (locale, { localeDir = './locale' } = {}) => { - // TODO: Translation file loading - // Always load from localeDir//LC_MESSAGES/messages.mo - //const filePath = path.resolve(localeDir, locale, 'LC_MESSAGES', 'messages.mo'); - //const moFile = fs.readFileSync(moFile, 'utf-8'); - //const { translations } = moFile; + var translations = {}; - const translator = new Translator(locale); + // TODO: Currently only a domain of 'messages' is supported + const filePath = path.resolve(localeDir, locale, 'LC_MESSAGES', 'messages.mo'); + + if (fs.existsSync(filePath)) { + const moFile = fs.readFileSync(filePath); + var { translations } = gettextParser.mo.parse(moFile, 'utf-8'); + } + + const translator = new Translator(locale, translations); return translator; diff --git a/test/fixtures/locale/README.md b/test/fixtures/locale/README.md new file mode 100644 index 0000000..0710faf --- /dev/null +++ b/test/fixtures/locale/README.md @@ -0,0 +1,12 @@ +Test Locales +============ + +This directory contains locales used for unit testing. + +To update locales from the pot file run the following: + + msgmerge --update fr/LC_MESSAGES/messages.po messages.pot + +To compile .mo files: + + msgfmt fr/LC_MESSAGES/messages.po -o fr/LC_MESSAGES/messages.mo diff --git a/test/fixtures/locale/fr/LC_MESSAGES/messages.mo b/test/fixtures/locale/fr/LC_MESSAGES/messages.mo new file mode 100644 index 0000000..14e29c5 Binary files /dev/null and b/test/fixtures/locale/fr/LC_MESSAGES/messages.mo differ diff --git a/test/fixtures/locale/fr/LC_MESSAGES/messages.po b/test/fixtures/locale/fr/LC_MESSAGES/messages.po new file mode 100644 index 0000000..c0e3a43 --- /dev/null +++ b/test/fixtures/locale/fr/LC_MESSAGES/messages.po @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: react-g 11n\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-01-15 20:51+0000\n" +"PO-Revision-Date: 2017-01-27 14:35+0000\n" +"Last-Translator: Darren Lucas \n" +"Language-Team: French\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "hello" +msgstr "bonjour" diff --git a/test/fixtures/locale/messages.pot b/test/fixtures/locale/messages.pot new file mode 100644 index 0000000..e495015 --- /dev/null +++ b/test/fixtures/locale/messages.pot @@ -0,0 +1,14 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Language-Team: LANGUAGE \n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"POT-Creation-Date: 2017-01-15 20:51+0000\n" + +msgid "hello" +msgstr "" diff --git a/test/localizer.test.js b/test/localizer.test.js index 5e8d5bb..89b10d3 100644 --- a/test/localizer.test.js +++ b/test/localizer.test.js @@ -24,3 +24,26 @@ test('Localizer', () => { ); }); + +test('Localizer with localeDir', () => { + + class DummyComponent extends Component { + render() { + expect(this.context.locale).toBe('fr'); + expect(this.context.translator.translate('hello')).toBe('bonjour'); + return null + } + } + + DummyComponent.contextTypes = { + locale: PropTypes.string, + translator: PropTypes.object + }; + + renderer.create( + + + + ); + +}); diff --git a/test/translator-factory.test.js b/test/translator-factory.test.js new file mode 100644 index 0000000..9d03b1b --- /dev/null +++ b/test/translator-factory.test.js @@ -0,0 +1,15 @@ +import translatorFactory from '../src/translator-factory'; + +const options = { + localeDir: './test/fixtures/locale' +} + +test('translatorFactory', () => { + const translator = translatorFactory('fr', options); + expect(translator.translate('hello')).toBe('bonjour'); +}); + +test('translatorFactory with missing locale', () => { + const translator = translatorFactory('es', options); + expect(translator.translate('hello')).toBe('hello'); +});