fix(i18n,client): translatable cta url (#41384)

This commit is contained in:
Nicholas Carrigan (he/him)
2021-03-12 16:14:54 -08:00
committed by GitHub
parent c198d508be
commit f1c8a9825b
14 changed files with 113 additions and 40 deletions

View File

@@ -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

View File

@@ -26,6 +26,9 @@ const filesThatShouldExist = [
},
{
name: 'meta-tags.json'
},
{
name: 'links.json'
}
];

View File

@@ -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/"
}
}

View File

@@ -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"
}
}

View File

@@ -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</0>.",
"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:",

View File

@@ -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"
}
}

View File

@@ -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);

View File

@@ -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.`);
}
}

View File

@@ -35,7 +35,7 @@ export const DonationOptionsText = () => {
</h4>
<p>
<Trans i18nKey='donate.other-ways'>
<a href={t('donate.other-ways-url')}>placeholder</a>
<a href={t('links:donate.other-ways-url')}>placeholder</a>
</Trans>
</p>
</>
@@ -48,7 +48,7 @@ export const DonationOptionsAlertText = () => {
<p>
<Trans>donate.bigger-donation</Trans>{' '}
<Trans i18nKey='donate.other-ways'>
<a href={t('donate.other-ways-url')}>placeholder</a>
<a href={t('links:donate.other-ways-url')}>placeholder</a>
</Trans>
</p>
);

View File

@@ -295,7 +295,7 @@ exports[`<Footer /> matches snapshot 1`] = `
className="our-nonprofit"
>
<a
href="footer.links.about-url"
href="links:footer.about-url"
rel="noopener noreferrer"
target="_blank"
>
@@ -316,56 +316,56 @@ exports[`<Footer /> matches snapshot 1`] = `
footer.links.open-source
</a>
<a
href="footer.links.shop-url"
href="links:footer.shop-url"
rel="noopener noreferrer"
target="_blank"
>
footer.links.shop
</a>
<a
href="footer.links.support-url"
href="links:footer.support-url"
rel="noopener noreferrer"
target="_blank"
>
footer.links.support
</a>
<a
href="footer.links.sponsors-url"
href="links:footer.sponsors-url"
rel="noopener noreferrer"
target="_blank"
>
footer.links.sponsors
</a>
<a
href="footer.links.honesty-url"
href="links:footer.honesty-url"
rel="noopener noreferrer"
target="_blank"
>
footer.links.honesty
</a>
<a
href="footer.links.coc-url"
href="links:footer.coc-url"
rel="noopener noreferrer"
target="_blank"
>
footer.links.coc
</a>
<a
href="footer.links.privacy-url"
href="links:footer.privacy-url"
rel="noopener noreferrer"
target="_blank"
>
footer.links.privacy
</a>
<a
href="footer.links.tos-url"
href="links:footer.tos-url"
rel="noopener noreferrer"
target="_blank"
>
footer.links.tos
</a>
<a
href="footer.links.copyright-url"
href="links:footer.copyright-url"
rel="noopener noreferrer"
target="_blank"
>

View File

@@ -145,7 +145,7 @@ function Footer() {
<div className='col-header'>{t('footer.our-nonprofit')}</div>
<div className='footer-divder' />
<div className='our-nonprofit'>
<Link external={false} to={t('footer.links.about-url')}>
<Link external={false} to={t('links:footer.about-url')}>
{t('footer.links.about')}
</Link>
<Link
@@ -161,29 +161,29 @@ function Footer() {
<Link
external={false}
sameTab={false}
to={t('footer.links.shop-url')}
to={t('links:footer.shop-url')}
>
{t('footer.links.shop')}
</Link>
<Link external={false} to={t('footer.links.support-url')}>
<Link external={false} to={t('links:footer.support-url')}>
{t('footer.links.support')}
</Link>
<Link external={false} to={t('footer.links.sponsors-url')}>
<Link external={false} to={t('links:footer.sponsors-url')}>
{t('footer.links.sponsors')}
</Link>
<Link external={false} to={t('footer.links.honesty-url')}>
<Link external={false} to={t('links:footer.honesty-url')}>
{t('footer.links.honesty')}
</Link>
<Link external={false} to={t('footer.links.coc-url')}>
<Link external={false} to={t('links:footer.coc-url')}>
{t('footer.links.coc')}
</Link>
<Link external={false} to={t('footer.links.privacy-url')}>
<Link external={false} to={t('links:footer.privacy-url')}>
{t('footer.links.privacy')}
</Link>
<Link external={false} to={t('footer.links.tos-url')}>
<Link external={false} to={t('links:footer.tos-url')}>
{t('footer.links.tos')}
</Link>
<Link external={false} to={t('footer.links.copyright-url')}>
<Link external={false} to={t('links:footer.copyright-url')}>
{t('footer.links.copyright')}
</Link>
</div>

View File

@@ -93,7 +93,7 @@ function renderLearnMap(nodes, currentSuperBlock = '') {
<Link
external={true}
sameTab={false}
to='https://contribute.freecodecamp.org/#/how-to-translate-files'
to={i18next.t('links:help-translate-link-url')}
>
{i18next.t('learn.help-translate-link')}
</Link>

View File

@@ -26,7 +26,7 @@ function ChallengeTitle({
{translationPending && (
<Link
className='title-translation-cta'
to='https://contribute.freecodecamp.org/#/how-to-translate-files'
to={i18next.t('links:help-translate-link-url')}
>
{i18next.t('misc.translation-pending')}
</Link>

View File

@@ -146,7 +146,7 @@ export class Block extends Component {
<div className='block-cta-wrapper'>
<Link
className='block-title-translation-cta'
to='https://contribute.freecodecamp.org/#/how-to-translate-files'
to={t('links:help-translate-link-url')}
>
{t('misc.translation-pending')}
</Link>
@@ -174,7 +174,7 @@ export class Block extends Component {
<div className='block-cta-wrapper'>
<Link
className='block-title-translation-cta'
to='https://contribute.freecodecamp.org/#/how-to-translate-files'
to={t('links:help-translate-link-url')}
>
{t('misc.translation-pending')}
</Link>