From 0d9268ad8683fa84a63f0ecad170f31b17e858a8 Mon Sep 17 00:00:00 2001 From: Daniel Lockyer Date: Wed, 18 Jan 2023 13:21:17 +0100 Subject: [PATCH] Added i18n package refs https://github.com/TryGhost/Ghost/issues/15502 - this is an early implementation of an i18n provider by exporting an instance of `i18next` - there's a lot more to be done here but baby steps :) --- ghost/i18n/.eslintrc.js | 6 ++++++ ghost/i18n/README.md | 17 +++++++++++++++++ ghost/i18n/index.js | 1 + ghost/i18n/lib/i18n.js | 23 +++++++++++++++++++++++ ghost/i18n/locales/en.js | 6 ++++++ ghost/i18n/locales/nl.js | 5 +++++ ghost/i18n/package.json | 28 ++++++++++++++++++++++++++++ ghost/i18n/test/.eslintrc.js | 6 ++++++ ghost/i18n/test/i18n.test.js | 29 +++++++++++++++++++++++++++++ yarn.lock | 22 +++++++++++++++++----- 10 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 ghost/i18n/.eslintrc.js create mode 100644 ghost/i18n/README.md create mode 100644 ghost/i18n/index.js create mode 100644 ghost/i18n/lib/i18n.js create mode 100644 ghost/i18n/locales/en.js create mode 100644 ghost/i18n/locales/nl.js create mode 100644 ghost/i18n/package.json create mode 100644 ghost/i18n/test/.eslintrc.js create mode 100644 ghost/i18n/test/i18n.test.js diff --git a/ghost/i18n/.eslintrc.js b/ghost/i18n/.eslintrc.js new file mode 100644 index 00000000000..c9c1bcb5226 --- /dev/null +++ b/ghost/i18n/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['ghost'], + extends: [ + 'plugin:ghost/node' + ] +}; diff --git a/ghost/i18n/README.md b/ghost/i18n/README.md new file mode 100644 index 00000000000..052d15cb53c --- /dev/null +++ b/ghost/i18n/README.md @@ -0,0 +1,17 @@ +# i18n + +i18n translations for Ghost + +## Develop + +This is a monorepo package. + +Follow the instructions for the top-level repo. +1. `git clone` this repo & `cd` into it as usual +2. Run `yarn` to install top-level dependencies. + +## Test + +- `yarn lint` run just eslint +- `yarn test` run lint and tests + diff --git a/ghost/i18n/index.js b/ghost/i18n/index.js new file mode 100644 index 00000000000..3b0b57fae1f --- /dev/null +++ b/ghost/i18n/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/i18n'); diff --git a/ghost/i18n/lib/i18n.js b/ghost/i18n/lib/i18n.js new file mode 100644 index 00000000000..5d61e2d9274 --- /dev/null +++ b/ghost/i18n/lib/i18n.js @@ -0,0 +1,23 @@ +const i18next = require('i18next'); + +module.exports = (lng = 'en') => { + const i18nextInstance = i18next.createInstance(); + i18nextInstance.init({ + lng, + debug: process.env.NODE_ENV === 'development', + + // allow keys to be phrases having `:`, `.` + nsSeparator: false, + keySeparator: false, + + // do not load a fallback + fallbackLng: false, + + resources: { + en: require('../locales/en.js'), + nl: require('../locales/nl.js') + } + }); + + return i18nextInstance; +}; diff --git a/ghost/i18n/locales/en.js b/ghost/i18n/locales/en.js new file mode 100644 index 00000000000..f79e140abba --- /dev/null +++ b/ghost/i18n/locales/en.js @@ -0,0 +1,6 @@ +// Note: we probably don't need anything in here because we don't expect +// to translate English to English, but it's here for completeness +module.exports = { + translation: { + } +}; diff --git a/ghost/i18n/locales/nl.js b/ghost/i18n/locales/nl.js new file mode 100644 index 00000000000..fdded27c405 --- /dev/null +++ b/ghost/i18n/locales/nl.js @@ -0,0 +1,5 @@ +module.exports = { + translation: { + 'Hello': 'Hallo' + } +}; diff --git a/ghost/i18n/package.json b/ghost/i18n/package.json new file mode 100644 index 00000000000..aa7d33dcd51 --- /dev/null +++ b/ghost/i18n/package.json @@ -0,0 +1,28 @@ +{ + "name": "@tryghost/i18n", + "version": "0.0.0", + "repository": "https://github.com/TryGhost/Ghost/tree/main/ghost/i18n", + "author": "Ghost Foundation", + "private": true, + "main": "index.js", + "scripts": { + "dev": "echo \"Implement me!\"", + "test:unit": "NODE_ENV=testing c8 --all --check-coverage --100 --reporter text --reporter cobertura mocha './test/**/*.test.js'", + "test": "yarn test:unit", + "lint:code": "eslint *.js lib/ --ext .js --cache", + "lint": "yarn lint:code && yarn lint:test", + "lint:test": "eslint -c test/.eslintrc.js test/ --ext .js --cache" + }, + "files": [ + "index.js", + "lib", + "locales" + ], + "devDependencies": { + "c8": "7.12.0", + "mocha": "10.2.0" + }, + "dependencies": { + "i18next": "22.4.8" + } +} diff --git a/ghost/i18n/test/.eslintrc.js b/ghost/i18n/test/.eslintrc.js new file mode 100644 index 00000000000..829b601eb0a --- /dev/null +++ b/ghost/i18n/test/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['ghost'], + extends: [ + 'plugin:ghost/test' + ] +}; diff --git a/ghost/i18n/test/i18n.test.js b/ghost/i18n/test/i18n.test.js new file mode 100644 index 00000000000..9fe36ec484b --- /dev/null +++ b/ghost/i18n/test/i18n.test.js @@ -0,0 +1,29 @@ +const assert = require('assert'); + +const i18n = require('../'); + +describe('Can translate', function () { + describe('Dutch', function () { + let t; + + before(function () { + t = i18n('nl').t; + }); + + it('can translate Dutch', function () { + assert.equal(t('Hello'), 'Hallo'); + }); + }); + + describe('English', function () { + let t; + + before(function () { + t = i18n('en').t; + }); + + it('can translate English', function () { + assert.equal(t('Hello'), 'Hello'); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index 5ff9ddd9ec1..9607c28e862 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1758,12 +1758,12 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.4.tgz#a42f814502ee467d55b38dd1c256f53a7b885c78" - integrity sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA== +"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.20.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd" + integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ== dependencies: - regenerator-runtime "^0.13.4" + regenerator-runtime "^0.13.11" "@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3": version "7.20.7" @@ -15376,6 +15376,13 @@ husky@8.0.3: resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== +i18next@22.4.8: + version "22.4.8" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-22.4.8.tgz#7a3c5d26a93e8e5f32eee07b58484e2f721fb45b" + integrity sha512-XSOy17ZWqflOiJRYE/dzv6vDle2Se32dnHREHb93UnZzZ1+UnvQ8yKtt1fpNL3zvXz5AwCqqixrtTVZmRetaiQ== + dependencies: + "@babel/runtime" "^7.20.6" + iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -22631,6 +22638,11 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.9: version "0.13.10" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee"