diff --git a/ghost/i18n/lib/i18n.js b/ghost/i18n/lib/i18n.js index 4938129df8..127b98f9ca 100644 --- a/ghost/i18n/lib/i18n.js +++ b/ghost/i18n/lib/i18n.js @@ -62,6 +62,26 @@ const SUPPORTED_LOCALES = [ 'ta' // Tamil ]; +function generateResources(locales, ns) { + return locales.reduce((acc, locale) => { + let res; + // add an extra fallback - this handles the case where we have a partial set of translations for some reason + // by falling back to the english translations + try { + res = require(`../locales/${locale}/${ns}.json`); + } catch (err) { + res = require(`../locales/en/${ns}.json`); + } + + // Note: due some random thing in TypeScript, 'requiring' a JSON file with a space in a key name, only adds it to the default export + // If changing this behaviour, please also check the comments and signup-form apps in another language (mainly sentences with a space in them) + acc[locale] = { + [ns]: {...res, ...(res.default && typeof res.default === 'object' ? res.default : {})} + }; + return acc; + }, {}); +} + /** * @param {string} [lng] * @param {'ghost'|'portal'|'test'|'signup-form'|'comments'|'search'|'newsletter'} ns @@ -75,6 +95,8 @@ module.exports = (lng = 'en', ns = 'portal') => { suffix: '}' }; } + + let resources = generateResources(SUPPORTED_LOCALES, ns); i18nextInstance.init({ lng, @@ -94,19 +116,11 @@ module.exports = (lng = 'en', ns = 'portal') => { // separators interpolation, - resources: SUPPORTED_LOCALES.reduce((acc, locale) => { - const res = require(`../locales/${locale}/${ns}.json`); - - // Note: due some random thing in TypeScript, 'requiring' a JSON file with a space in a key name, only adds it to the default export - // If changing this behaviour, please also check the comments and signup-form apps in another language (mainly sentences with a space in them) - acc[locale] = { - [ns]: {...res, ...(res.default && typeof res.default === 'object' ? res.default : {})} - }; - return acc; - }, {}) + resources }); return i18nextInstance; }; module.exports.SUPPORTED_LOCALES = SUPPORTED_LOCALES; +module.exports.generateResources = generateResources; \ No newline at end of file diff --git a/ghost/i18n/test/i18n.test.js b/ghost/i18n/test/i18n.test.js index fd4a744a7b..6f8d08dd4e 100644 --- a/ghost/i18n/test/i18n.test.js +++ b/ghost/i18n/test/i18n.test.js @@ -96,4 +96,11 @@ describe('i18n', function () { assert.equal(t('Your subscription will renew on {date}.', {date: '8 Oct 2024'}), 'Votre abonnement sera renouvelé le 8 Oct 2024.'); }); }); + describe('it gracefully falls back to en if a file is missing', function () { + it('should be able to translate a key that is missing in the locale', async function () { + const resources = i18n.generateResources(['xx'], 'portal'); + const englishResources = i18n.generateResources(['en'], 'portal'); + assert.deepEqual(resources.xx, englishResources.en); + }); + }); });