From f1c8a9825b7354bfbca739591648722223c7cafe Mon Sep 17 00:00:00 2001 From: "Nicholas Carrigan (he/him)" Date: Fri, 12 Mar 2021 16:14:54 -0800 Subject: [PATCH] fix(i18n,client): translatable cta url (#41384) --- client/i18n/config.js | 8 ++++--- client/i18n/locales.test.js | 3 +++ client/i18n/locales/chinese/links.json | 17 +++++++++++++ client/i18n/locales/english/links.json | 17 +++++++++++++ client/i18n/locales/english/translations.json | 12 +--------- client/i18n/locales/espanol/links.json | 17 +++++++++++++ client/i18n/schema-validation.js | 24 +++++++++++++++++-- client/i18n/validate-keys.js | 7 ++++++ .../Donation/DonationTextComponents.js | 4 ++-- .../Footer/__snapshots__/Footer.test.js.snap | 18 +++++++------- client/src/components/Footer/index.js | 18 +++++++------- client/src/components/Map/index.js | 2 +- .../Challenges/components/Challenge-Title.js | 2 +- .../Introduction/components/Block.js | 4 ++-- 14 files changed, 113 insertions(+), 40 deletions(-) create mode 100644 client/i18n/locales/chinese/links.json create mode 100644 client/i18n/locales/english/links.json create mode 100644 client/i18n/locales/espanol/links.json diff --git a/client/i18n/config.js b/client/i18n/config.js index 89b0fd18a1..24a5c3b0d4 100644 --- a/client/i18n/config.js +++ b/client/i18n/config.js @@ -15,16 +15,18 @@ i18n.use(initReactI18next).init({ translations: require(`./locales/${clientLocale}/translations.json`), trending: require(`./locales/${clientLocale}/trending.json`), intro: require(`./locales/${clientLocale}/intro.json`), - metaTags: require(`./locales/${clientLocale}/meta-tags.json`) + metaTags: require(`./locales/${clientLocale}/meta-tags.json`), + links: require(`./locales/${clientLocale}/links.json`) }, en: { translations: require('./locales/english/translations.json'), trending: require('./locales/english/trending.json'), intro: require('./locales/english/intro.json'), - metaTags: require('./locales/english/meta-tags.json') + metaTags: require('./locales/english/meta-tags.json'), + links: require('./locales/english/links.json') } }, - ns: ['translations', 'trending', 'intro', 'metaTags'], + ns: ['translations', 'trending', 'intro', 'metaTags', 'links'], defaultNS: 'translations', returnObjects: true, // Uncomment the next line for debug logging diff --git a/client/i18n/locales.test.js b/client/i18n/locales.test.js index a4d24b6014..9f6f0d5479 100644 --- a/client/i18n/locales.test.js +++ b/client/i18n/locales.test.js @@ -26,6 +26,9 @@ const filesThatShouldExist = [ }, { name: 'meta-tags.json' + }, + { + name: 'links.json' } ]; diff --git a/client/i18n/locales/chinese/links.json b/client/i18n/locales/chinese/links.json new file mode 100644 index 0000000000..2244aa8127 --- /dev/null +++ b/client/i18n/locales/chinese/links.json @@ -0,0 +1,17 @@ +{ + "help-translate-url": "https://contribute.freecodecamp.org/#/i18n/chinese/how-to-translate-files", + "footer": { + "about-url": "https://chinese.freecodecamp.org/news/about/", + "shop-url": "https://www.freecodecamp.org/shop/", + "support-url": "https://chinese.freecodecamp.org/news/support/", + "sponsors-url": "https://www.freecodecamp.org/news/sponsors/", + "honesty-url": "https://chinese.freecodecamp.org/news/academic-honesty-policy/", + "coc-url": "https://chinese.freecodecamp.org/news/code-of-conduct/", + "privacy-url": "https://www.freecodecamp.org/news/privacy-policy/", + "tos-url": "https://www.freecodecamp.org/news/terms-of-service/", + "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" + }, + "donate": { + "other-ways-url": "https://chinese.freecodecamp.org/news/how-to-donate-to-free-code-camp/" + } +} diff --git a/client/i18n/locales/english/links.json b/client/i18n/locales/english/links.json new file mode 100644 index 0000000000..a3f22393f4 --- /dev/null +++ b/client/i18n/locales/english/links.json @@ -0,0 +1,17 @@ +{ + "help-translate-link-url": "https://contribute.freecodecamp.org/#/how-to-translate-files", + "footer": { + "about-url": "https://www.freecodecamp.org/news/about/", + "shop-url": "https://www.freecodecamp.org/shop/", + "support-url": "https://www.freecodecamp.org/news/support/", + "sponsors-url": "https://www.freecodecamp.org/news/sponsors/", + "honesty-url": "https://www.freecodecamp.org/news/academic-honesty-policy/", + "coc-url": "https://www.freecodecamp.org/news/code-of-conduct/", + "privacy-url": "https://www.freecodecamp.org/news/privacy-policy/", + "tos-url": "https://www.freecodecamp.org/news/terms-of-service/", + "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" + }, + "donate": { + "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp" + } +} diff --git a/client/i18n/locales/english/translations.json b/client/i18n/locales/english/translations.json index 24874d5d5f..f6a7bdacf0 100644 --- a/client/i18n/locales/english/translations.json +++ b/client/i18n/locales/english/translations.json @@ -217,25 +217,16 @@ "our-nonprofit": "Our Nonprofit", "links": { "about": "About", - "about-url": "https://www.freecodecamp.org/news/about/", "alumni": "Alumni Network", "open-source": "Open Source", "shop": "Shop", - "shop-url": "https://www.freecodecamp.org/shop/", "support": "Support", - "support-url": "https://www.freecodecamp.org/news/support/", "sponsors": "Sponsors", - "sponsors-url": "https://www.freecodecamp.org/news/sponsors/", "honesty": "Academic Honesty", - "honesty-url": "https://www.freecodecamp.org/news/academic-honesty-policy/", "coc": "Code of Conduct", - "coc-url": "https://www.freecodecamp.org/news/code-of-conduct/", "privacy": "Privacy Policy", - "privacy-url": "https://www.freecodecamp.org/news/privacy-policy/", "tos": "Terms of Service", - "tos-url": "https://www.freecodecamp.org/news/terms-of-service/", - "copyright": "Copyright Policy", - "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" + "copyright": "Copyright Policy" }, "language": "Language:" }, @@ -335,7 +326,6 @@ "why-donate-2": "You also help us create new resources for you to use to expand your own technology skills.", "bigger-donation": "Want to make a bigger one-time donation, mail us a check, or give in other ways?", "other-ways": "Here are many <0>other ways you can support our non-profit's mission.", - "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp", "failed-pay": "Uh - oh. It looks like your transaction didn't go through. Could you please try again?", "try-again": "Please try again.", "card-number": "Your Card Number:", diff --git a/client/i18n/locales/espanol/links.json b/client/i18n/locales/espanol/links.json new file mode 100644 index 0000000000..434aa8a085 --- /dev/null +++ b/client/i18n/locales/espanol/links.json @@ -0,0 +1,17 @@ +{ + "help-translate-link-url": "https://contribute.freecodecamp.org/#/i18n/espanol/how-to-translate-files", + "footer": { + "about-url": "https://www.freecodecamp.org/espanol/news/acerca-de-freecodecamp-preguntas-frecuentes/", + "shop-url": "https://www.freecodecamp.org/shop/", + "support-url": "https://www.freecodecamp.org/espanol/news/preguntas-comunes-de-soporte-tecnico/", + "sponsors-url": "https://www.freecodecamp.org/news/sponsors/", + "honesty-url": "https://www.freecodecamp.org/espanol/news/politica-de-honestidad-academica/", + "coc-url": "https://www.freecodecamp.org/espanol/news/codigo-de-conducta/", + "privacy-url": "https://www.freecodecamp.org/news/privacy-policy/", + "tos-url": "https://www.freecodecamp.org/news/terms-of-service/", + "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" + }, + "donate": { + "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp" + } +} diff --git a/client/i18n/schema-validation.js b/client/i18n/schema-validation.js index 1500942d2d..d4505c68b8 100644 --- a/client/i18n/schema-validation.js +++ b/client/i18n/schema-validation.js @@ -5,6 +5,7 @@ const trendingSchema = require('./locales/english/trending.json'); const motivationSchema = require('./locales/english/motivation.json'); const introSchema = require('./locales/english/intro.json'); const metaTagsSchema = require('./locales/english/meta-tags.json'); +const linksSchema = require('./locales/english/links.json'); /** * Flattens a nested object structure into a single @@ -106,6 +107,7 @@ const trendingSchemaKeys = Object.keys(flattenAnObject(trendingSchema)); const motivationSchemaKeys = Object.keys(flattenAnObject(motivationSchema)); const introSchemaKeys = Object.keys(flattenAnObject(introSchema)); const metaTagsSchemaKeys = Object.keys(flattenAnObject(metaTagsSchema)); +const linksSchemaKeys = Object.keys(flattenAnObject(linksSchema)); /** * Function that checks the translations.json file @@ -219,8 +221,8 @@ const introSchemaValidation = languages => { const filePath = path.join(__dirname, `/locales/${language}/intro.json`); const fileJson = require(filePath); const fileKeys = Object.keys(flattenAnObject(fileJson)); - findMissingKeys(fileKeys, introSchemaKeys, `${language}/intro.json`); - findExtraneousKeys(fileKeys, introSchemaKeys, `${language}/intro.json`); + findMissingKeys(fileKeys, linksSchemaKeys, `${language}/intro.json`); + findExtraneousKeys(fileKeys, linksSchemaKeys, `${language}/intro.json`); const emptyKeys = noEmptyObjectValues(fileJson); if (emptyKeys.length) { console.warn( @@ -257,6 +259,23 @@ const metaTagsSchemaValidation = languages => { }); }; +const linksSchemaValidation = languages => { + languages.forEach(language => { + const filePath = path.join(__dirname, `/locales/${language}/links.json`); + const fileJson = require(filePath); + const fileKeys = Object.keys(flattenAnObject(fileJson)); + findMissingKeys(fileKeys, introSchemaKeys, `${language}/links.json`); + findExtraneousKeys(fileKeys, introSchemaKeys, `${language}/links.json`); + const emptyKeys = noEmptyObjectValues(fileJson); + if (emptyKeys.length) { + console.warn( + `${language}/links.json has these empty keys: ${emptyKeys.join(', ')}` + ); + } + console.info(`${language} links.json validation complete`); + }); +}; + const translatedLangs = availableLangs.client.filter(x => x !== 'english'); translationSchemaValidation(translatedLangs); @@ -264,3 +283,4 @@ trendingSchemaValidation(translatedLangs); motivationSchemaValidation(translatedLangs); introSchemaValidation(translatedLangs); metaTagsSchemaValidation(translatedLangs); +linksSchemaValidation(translatedLangs); diff --git a/client/i18n/validate-keys.js b/client/i18n/validate-keys.js index 6eca265227..f2e9bbdb03 100644 --- a/client/i18n/validate-keys.js +++ b/client/i18n/validate-keys.js @@ -5,6 +5,7 @@ const introObject = require('./locales/english/intro.json'); const metaObject = require('./locales/english/meta-tags.json'); const motivationObject = require('./locales/english/motivation.json'); const trendingObject = require('./locales/english/trending.json'); +const linksObject = require('./locales/english/links.json'); /** * Function to flatten a nested object. Written specifically for @@ -35,6 +36,7 @@ const metaKeys = Object.keys(flattenAnObject(metaObject)); const motivationKeys = Object.keys(flattenAnObject(motivationObject)); const introKeys = Object.keys(flattenAnObject(introObject)); const trendingKeys = Object.keys(flattenAnObject(trendingObject)); +const linksKeys = Object.keys(flattenAnObject(linksObject)); /** * Recursively read through the directory, grabbing .js files @@ -89,3 +91,8 @@ for (const key of trendingKeys) { console.warn(`The trending key '${key}' appears to be unused.`); } } +for (const key of linksKeys) { + if (!clientCodebase.includes(key) && !serverCodebase.includes(key)) { + console.warn(`The links key '${key}' appears to be unused.`); + } +} diff --git a/client/src/components/Donation/DonationTextComponents.js b/client/src/components/Donation/DonationTextComponents.js index e862d68c63..8951177f4b 100644 --- a/client/src/components/Donation/DonationTextComponents.js +++ b/client/src/components/Donation/DonationTextComponents.js @@ -35,7 +35,7 @@ export const DonationOptionsText = () => {

- placeholder + placeholder

@@ -48,7 +48,7 @@ export const DonationOptionsAlertText = () => {

donate.bigger-donation{' '} - placeholder + placeholder

); diff --git a/client/src/components/Footer/__snapshots__/Footer.test.js.snap b/client/src/components/Footer/__snapshots__/Footer.test.js.snap index 7af2ed97d4..affa2e18d4 100644 --- a/client/src/components/Footer/__snapshots__/Footer.test.js.snap +++ b/client/src/components/Footer/__snapshots__/Footer.test.js.snap @@ -295,7 +295,7 @@ exports[`