Skip to content

Commit

Permalink
chore(admin-ui): Automate the extraction of all supported translations
Browse files Browse the repository at this point in the history
Relates to #356
  • Loading branch information
michaelbromley committed Jun 2, 2020
1 parent 8daee55 commit 04ec9de
Show file tree
Hide file tree
Showing 9 changed files with 2,208 additions and 433 deletions.
11 changes: 9 additions & 2 deletions packages/admin-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ Translation keys are automatically extracted by running:
```
yarn extract-translations
```
This will add any new translation keys to the default language file located in [`./src/lib/static/i18n-messages/en.json`](./src/lib/static/i18n-messages/en.json).
This scan the source files for any translation keys, and add them to each of the translation files located in [`./src/lib/static/i18n-messages/`](./src/lib/static/i18n-messages/).

To extract translations into other language, run the same command as specified in the `extract-translations` npm script, but substitute the "en" in "en.json" with the [ISO 639-1 2-character language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for that language.
A report is generated for each language detailing what percentage of the translation tokens are translated into that language:

```text
Extracting translation tokens for "src\lib\static\i18n-messages\de.json"
de: 592 of 650 tokens translated (91%)
```

To add support for a new language, create a new empty json file (`{}`) in the `i18n-messages` directory named `<languageCode>.json`, where `languageCode` is one of the supported codes as given in the [LanguageCode enum type](../core/src/api/schema/common/language-code.graphql), then run `yarn extract-translations`
3 changes: 2 additions & 1 deletion packages/admin-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"watch": "ng build --watch=true",
"test": "ng test --watch=false --browsers=ChromeHeadlessCI --progress=false",
"lint": "tslint --fix",
"extract-translations": "ngx-translate-extract --input ./src --output ./src/lib/static/i18n-messages/en.json --clean --sort --format namespaced-json --format-indentation \" \" -m _",
"extract-translations": "node scripts/extract-translations.js",
"ngcc": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points"
},
"publishConfig": {
Expand Down Expand Up @@ -79,6 +79,7 @@
"@types/prosemirror-state": "^1.2.3",
"@types/prosemirror-view": "^1.11.2",
"codelyzer": "^5.2.2",
"cross-spawn": "^7.0.3",
"fs-extra": "^9.0.0",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~5.0.1",
Expand Down
88 changes: 88 additions & 0 deletions packages/admin-ui/scripts/extract-translations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
const path = require('path');
const fs = require('fs-extra');
const spawn = require('cross-spawn');

const MESSAGES_DIR = path.join(__dirname, '../src/lib/static/i18n-messages');

extractTranslations().then(
() => {
process.exit(0);
},
(error) => {
console.log(error);
process.exit(1);
},
);

async function extractTranslations() {
const locales = fs.readdirSync(MESSAGES_DIR).map((file) => path.basename(file).replace('.json', ''));
for (const locale of locales) {
const outputPath = path.join(
path.relative(path.join(__dirname, '..'), MESSAGES_DIR),
`${locale}.json`,
);
console.log(`Extracting translation tokens for "${outputPath}"`);

try {
await runExtraction(locale);
const { tokenCount, translatedCount, percentage } = getStatsForLocale(locale);
console.log(`${locale}: ${translatedCount} of ${tokenCount} tokens translated (${percentage}%)`);
console.log('');
} catch (e) {
console.log(e);
}
}
}

function runExtraction(locale) {
const command = 'npm';
const args = getNgxTranslateExtractCommand(locale);
return new Promise((resolve, reject) => {
try {
const child = spawn(`yarnpkg`, args, { stdio: ['pipe', 'pipe', process.stderr] });
child.on('close', (x) => {
resolve();
});
child.on('error', (err) => {
reject(err);
});
} catch (e) {
reject(e);
}
});
}

function getStatsForLocale(locale) {
const content = fs.readJsonSync(path.join(MESSAGES_DIR, `${locale}.json`), 'utf-8');
let tokenCount = 0;
let translatedCount = 0;
for (const section of Object.keys(content)) {
const sectionTranslations = Object.values(content[section]);
tokenCount += sectionTranslations.length;
translatedCount += sectionTranslations.filter((val) => val !== '').length;
}
const percentage = Math.round((translatedCount / tokenCount) * 100);
return {
tokenCount,
translatedCount,
percentage,
};
}

function getNgxTranslateExtractCommand(locale) {
return [
`ngx-translate-extract`,
'--input',
'./src',
'--output',
`./src/lib/static/i18n-messages/${locale}.json`,
`--clean`,
`--sort`,
`--format`,
`namespaced-json`,
`--format-indentation`,
`" "`,
`-m`,
`_`,
];
}
Loading

0 comments on commit 04ec9de

Please sign in to comment.