Skip to content

Instantly share code, notes, and snippets.

@oxycoder
Last active May 21, 2020 16:38
Show Gist options
  • Save oxycoder/4ae18d520b5ffa3e8669e4e8932a4002 to your computer and use it in GitHub Desktop.
Save oxycoder/4ae18d520b5ffa3e8669e4e8932a4002 to your computer and use it in GitHub Desktop.
Export i18n from template and ts file for angular 9

To extract message, run following command:

yarn extract-i18n
{
"projects": {
"my-app": {
"architech": {
...
...
"xliffmerge": {
"builder": "@ngx-i18nsupport/tooling:xliffmerge",
"options": {
"xliffmergeOptions": {
"i18nFormat": "xlf",
"srcDir": "src/i18n",
"genDir": "src/i18n",
"defaultLanguage": "en",
"languages": [
"en",
"fr"
"ru"
"vi"
]
}
}
},
...
}
}
}
}
// path: tools/xlf-merge/index.js
#!/usr/bin/env node
const program = require('commander');
const fs = require('fs');
const convert = require('xml-js');
const shell = require('shelljs');
const mergeXlf = require('./merge-xlf');
function runMerge(inputPaths, outputPath) {
const inputFiles = (function*() { yield* shell.ls(inputPaths); })();
const sourceFile = inputFiles.next().value;
console.log('Initial file', sourceFile);
let fileContent = fs.readFileSync(sourceFile).toString();
let output = convert.xml2js(fileContent);
for (let fileIter = inputFiles.next(); !fileIter.done; fileIter = inputFiles.next()) {
fileContent = fs.readFileSync(fileIter.value).toString();
output = mergeXlf(output, convert.xml2js(fileContent), fileIter.value);
}
const outXml = convert.js2xml(output);
fs.writeFileSync(outputPath, outXml);
console.log('Generated output file', outputPath);
}
//runMerge(['data/test3/generic.xlf', 'data/test3/home-page.xlf', 'data/test3/lesson.xlf'], 'data/test3/out.xlf');
//return;
program
.version('1.0.3')
.usage('[options] <input files or pattern such as *.xlf ...>')
.option('-o, --output <output>', 'Output file name')
.parse(process.argv);
if (program.args === 0 || !program.output) {
program.help();
}
try {
runMerge(program.args, program.output);
}
catch (err) {
console.error(err);
}
# Angular 9 come with new Ivy engine, xi18n tool do not support for new engine so we can't extract translate messages.
# This script tool support extract i18n from templates and ts file
# Install require package
yarn add shx @locl/cli xml-js @ngx-i18nsupport/ngx-i18nsupport @ngx-i18nsupport/tooling
// path: tools/xlf-merge/merge-xlf.js
module.exports = function(first, second, fileName) {
function fail(message) {
throw new Error(message + ' File name: ' + fileName + '.');
}
function getElement(src, path, isOptional) {
let result = src;
let breadcrumbs = '';
for (const pnode of path) {
breadcrumbs += '/' + pnode;
if (!result.elements) {
if (!isOptional) {
fail(breadcrumbs + ' - expected element ' + pnode + ' not found. Make sure that the XLF file schema is correct.');
} else {
return null;
}
}
result = result.elements.find(e => e.name === pnode);
if (!result) {
if (!isOptional) {
fail('Element ' + breadcrumbs + ' not found. Make sure that the XLF file schema is correct.');
} else {
return null;
}
}
}
return result;
}
function getContent(src) {
const result = ((src && src.elements) || []).find(e => e.type === 'text');
return result ? result.text : '';
}
function* getTransUnits(root) {
if (!root.elements) {
console.log('Skipping ', fileName, '- no trans-units found.');
return;
}
for (const el of root.elements) {
if (el.name === 'trans-unit') {
yield el;
}
}
}
const transPath = ['xliff', 'file', 'body'];
const srcRoot = getElement(first, transPath);
const tgtRoot = getElement(second, transPath);
const tgtTransUnits = [...getTransUnits(tgtRoot)];
let numMergedTransUnits = 0;
function findTgtById(id) {
return tgtTransUnits.find(t => t.attributes && t.attributes.id === id);
}
for (const srcTransUnit of getTransUnits(srcRoot)) {
const id = srcTransUnit.attributes.id;
const content = getContent(getElement(srcTransUnit, ['target'], true));
const matchingTgt = findTgtById(id);
if (matchingTgt) {
const tgtContent = getContent(getElement(matchingTgt, ['target'], true));
if (content !== tgtContent) {
console.log(`"${content}"`, ' <- ', id, ' -> ', `"${tgtContent}"`);
}
} else {
tgtRoot.elements.push(srcTransUnit);
numMergedTransUnits++;
}
}
console.log(fileName, ' -> ', numMergedTransUnits, 'translations merged');
return second;
}
// Add following scripts to package.json file
// Asume
{
"merge-i18n": "node ./tools/xlf-merge/ src/i18n/tool/*.en.xlf -o src/i18n/messages.xlf",
"gen-i18n": "yarn shx rm -rf src/i18n/tool && yarn locl extract -s=dist/web/*.js -f=xlf -o=src/i18n/tool/ && yarn merge-i18n",
"extract-i18n": "ng build --prod && yarn gen-i18n && ng run my-app:xliffmerge && yarn shx rm -rf src/i18n/tool",
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment