From 95a2da64107db655e6e1d7ba1dca3eac9b4bb94d Mon Sep 17 00:00:00 2001 From: Bill Branan Date: Thu, 26 Aug 2021 09:37:53 -0400 Subject: [PATCH 1/3] Adds script to merge in i18n translation files from themes See: https://github.com/DSpace/dspace-angular/issues/1299 --- package.json | 1 + scripts/merge-i18n-files.ts | 100 +++++++++++++++++++++++++ src/themes/custom/assets/i18n/en.json5 | 7 ++ 3 files changed, 108 insertions(+) create mode 100644 scripts/merge-i18n-files.ts create mode 100644 src/themes/custom/assets/i18n/en.json5 diff --git a/package.json b/package.json index 652ab409ac..6005172328 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "clean": "yarn run clean:prod && yarn run clean:env && yarn run clean:node", "clean:env": "rimraf src/environments/environment.ts", "sync-i18n": "yarn run config:dev && ts-node --project ./tsconfig.ts-node.json scripts/sync-i18n-files.ts", + "merge-i18n": "yarn run config:dev && ts-node --project ./tsconfig.ts-node.json scripts/merge-i18n-files.ts", "postinstall": "ngcc" }, "browser": { diff --git a/scripts/merge-i18n-files.ts b/scripts/merge-i18n-files.ts new file mode 100644 index 0000000000..fc44665f7c --- /dev/null +++ b/scripts/merge-i18n-files.ts @@ -0,0 +1,100 @@ +import { projectRoot} from '../webpack/helpers'; +const commander = require('commander'); +const fs = require('fs'); +const JSON5 = require('json5'); +const _cliProgress = require('cli-progress'); +const _ = require('lodash'); + +const program = new commander.Command(); +program.version('1.0.0', '-v, --version'); + +const LANGUAGE_FILES_LOCATION = 'src/assets/i18n'; + +parseCliInput(); + +/** + * Purpose: Allows customization of i18n labels from within themes + * e.g. Customize the label "menu.section.browse_global" to display "Browse DSpace" rather than "All of DSpace" + * + * This script uses the i18n files found in a source directory to override settings in files with the same + * name in a destination directory. Only the i18n labels to be overridden need be in the source files. + * + * Execution (using custom theme): + * ``` + * yarn merge-i18n -s src/themes/custom/assets/i18n + * ``` + * + * Input parameters: + * * Output directory: The directory in which the original i18n files are stored + * - Defaults to src/assets/i18n (the default i18n file location) + * - This is where the final output files will be written + * * Source directory: The directory with override files + * - Required + * - Recommended to place override files in the theme directory under assets/i18n (but this is not required) + * - Files must have matching names in both source and destination directories, for example: + * en.json5 in the source directory will be merged with en.json5 in the destination directory + * fr.json5 in the source directory will be merged with fr.json5 in the destination directory + */ +function parseCliInput() { + program + .option('-d, --output-dir ', 'output dir when running script on all language files', projectRoot(LANGUAGE_FILES_LOCATION)) + .option('-s, --source-dir ', 'source dir of transalations to be merged') + .usage('(-s [-d ])') + .parse(process.argv); + + if (program.outputDir && program.sourceDir) { + if (!fs.existsSync(program.outputDir) && !fs.lstatSync(program.outputDir).isDirectory() ) { + console.error('Output does not exist or is not a directory.'); + console.log(program.outputHelp()); + process.exit(1); + } + if (!fs.existsSync(program.sourceDir) && !fs.lstatSync(program.sourceDir).isDirectory() ) { + console.error('Source does not exist or is not a directory.'); + console.log(program.outputHelp()); + process.exit(1); + } + fs.readdirSync(projectRoot(program.sourceDir)).forEach(file => { + if (fs.existsSync(program.outputDir + '/' + file) ) + { + console.log("Merging: "+ program.outputDir + '/' + file + ' with '+ program.sourceDir + '/' + file) + mergeFileWithSource(program.sourceDir + '/' + file, program.outputDir + '/' + file) + } + }); + } else { + console.error('Source or Output parameter is missing.'); + console.log(program.outputHelp()); + process.exit(1); + } +} + +/** + * Reads source file and output file to merge the contents + * > Iterates over the source file keys + * > Updates values for each key and adds new keys as needed + * > Updates the output file with the new merged json + * @param pathToSourceFile Valid path to source file to merge from + * @param pathToOutputFile Valid path to merge and write output + */ +function mergeFileWithSource(pathToSourceFile, pathToOutputFile) { + const progressBar = new _cliProgress.SingleBar({}, _cliProgress.Presets.shades_classic); + progressBar.start(100, 0); + + const source_file = fs.readFileSync(pathToSourceFile, 'utf8') + progressBar.update(10); + const output_file = fs.readFileSync(pathToOutputFile, 'utf8') + progressBar.update(20); + + let parsed_source = JSON5.parse(source_file) + progressBar.update(30); + let parsed_output = JSON5.parse(output_file) + progressBar.update(40); + + for (let key of Object.keys(parsed_source)) { + parsed_output[key] = parsed_source[key]; + } + progressBar.update(80); + fs.writeFileSync(pathToOutputFile,JSON5.stringify(parsed_output,{space:'\n '}), {encoding:'utf8'}) + + progressBar.update(100); + progressBar.stop(); +} diff --git a/src/themes/custom/assets/i18n/en.json5 b/src/themes/custom/assets/i18n/en.json5 new file mode 100644 index 0000000000..bdca353f13 --- /dev/null +++ b/src/themes/custom/assets/i18n/en.json5 @@ -0,0 +1,7 @@ +{ + // DSpace default: "All of DSpace" + "menu.section.browse_global": "Browse DSpace", + + // DSpace default: "DSpace Angular :: " + "repository.title.prefix": "DSpace :: ", +} From 81988179e90963b67fab50da7647fc98c61ebe25 Mon Sep 17 00:00:00 2001 From: Bill Branan Date: Tue, 31 Aug 2021 15:47:46 -0400 Subject: [PATCH 2/3] Adds setting to maintain the use of double quotes --- scripts/merge-i18n-files.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/merge-i18n-files.ts b/scripts/merge-i18n-files.ts index fc44665f7c..f184b46217 100644 --- a/scripts/merge-i18n-files.ts +++ b/scripts/merge-i18n-files.ts @@ -93,7 +93,7 @@ function mergeFileWithSource(pathToSourceFile, pathToOutputFile) { parsed_output[key] = parsed_source[key]; } progressBar.update(80); - fs.writeFileSync(pathToOutputFile,JSON5.stringify(parsed_output,{space:'\n '}), {encoding:'utf8'}) + fs.writeFileSync(pathToOutputFile,JSON5.stringify(parsed_output,{ space:'\n ', quote: '"' }), { encoding:'utf8' }) progressBar.update(100); progressBar.stop(); From edb814c49a1c5cd44cd1119efa0fe568b25732c1 Mon Sep 17 00:00:00 2001 From: Bill Branan Date: Tue, 31 Aug 2021 15:59:09 -0400 Subject: [PATCH 3/3] Updates formatting to follow code style rules --- scripts/merge-i18n-files.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/scripts/merge-i18n-files.ts b/scripts/merge-i18n-files.ts index f184b46217..e790828c0d 100644 --- a/scripts/merge-i18n-files.ts +++ b/scripts/merge-i18n-files.ts @@ -54,10 +54,9 @@ function parseCliInput() { process.exit(1); } fs.readdirSync(projectRoot(program.sourceDir)).forEach(file => { - if (fs.existsSync(program.outputDir + '/' + file) ) - { - console.log("Merging: "+ program.outputDir + '/' + file + ' with '+ program.sourceDir + '/' + file) - mergeFileWithSource(program.sourceDir + '/' + file, program.outputDir + '/' + file) + if (fs.existsSync(program.outputDir + '/' + file) ) { + console.log('Merging: ' + program.outputDir + '/' + file + ' with ' + program.sourceDir + '/' + file); + mergeFileWithSource(program.sourceDir + '/' + file, program.outputDir + '/' + file); } }); } else { @@ -79,21 +78,21 @@ function mergeFileWithSource(pathToSourceFile, pathToOutputFile) { const progressBar = new _cliProgress.SingleBar({}, _cliProgress.Presets.shades_classic); progressBar.start(100, 0); - const source_file = fs.readFileSync(pathToSourceFile, 'utf8') + const sourceFile = fs.readFileSync(pathToSourceFile, 'utf8'); progressBar.update(10); - const output_file = fs.readFileSync(pathToOutputFile, 'utf8') + const outputFile = fs.readFileSync(pathToOutputFile, 'utf8'); progressBar.update(20); - let parsed_source = JSON5.parse(source_file) + const parsedSource = JSON5.parse(sourceFile); progressBar.update(30); - let parsed_output = JSON5.parse(output_file) + const parsedOutput = JSON5.parse(outputFile); progressBar.update(40); - for (let key of Object.keys(parsed_source)) { - parsed_output[key] = parsed_source[key]; + for (const key of Object.keys(parsedSource)) { + parsedOutput[key] = parsedSource[key]; } progressBar.update(80); - fs.writeFileSync(pathToOutputFile,JSON5.stringify(parsed_output,{ space:'\n ', quote: '"' }), { encoding:'utf8' }) + fs.writeFileSync(pathToOutputFile,JSON5.stringify(parsedOutput,{ space:'\n ', quote: '"' }), { encoding:'utf8' }); progressBar.update(100); progressBar.stop();