diff --git a/package-lock.json b/package-lock.json index 7037b447fd35..326bf162d1c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -118,6 +118,7 @@ "cross-env": "^7.0.3", "csp-parse": "0.0.2", "css-loader": "^4.3.0", + "csv-parse": "^4.16.0", "dedent": "^0.7.0", "domwaiter": "^1.3.0", "eslint": "^7.28.0", @@ -8510,6 +8511,12 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/csv-parse": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.0.tgz", + "integrity": "sha512-Zb4tGPANH4SW0LgC9+s9Mnequs9aqn7N3/pCqNbVjs2XhEF6yWNU2Vm4OGl1v2Go9nw8rXt87Cm2QN/o6Vpqgg==", + "dev": true + }, "node_modules/cwd": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/cwd/-/cwd-0.10.0.tgz", @@ -32079,6 +32086,12 @@ } } }, + "csv-parse": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.0.tgz", + "integrity": "sha512-Zb4tGPANH4SW0LgC9+s9Mnequs9aqn7N3/pCqNbVjs2XhEF6yWNU2Vm4OGl1v2Go9nw8rXt87Cm2QN/o6Vpqgg==", + "dev": true + }, "cwd": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/cwd/-/cwd-0.10.0.tgz", diff --git a/package.json b/package.json index 0d1015c119b5..13ad268d9d68 100644 --- a/package.json +++ b/package.json @@ -124,6 +124,7 @@ "cross-env": "^7.0.3", "csp-parse": "0.0.2", "css-loader": "^4.3.0", + "csv-parse": "^4.16.0", "dedent": "^0.7.0", "domwaiter": "^1.3.0", "eslint": "^7.28.0", diff --git a/script/content-migrations/create-csv-of-short-titles.js b/script/content-migrations/create-csv-of-short-titles.js new file mode 100755 index 000000000000..6d1dd7250970 --- /dev/null +++ b/script/content-migrations/create-csv-of-short-titles.js @@ -0,0 +1,22 @@ +#!/usr/bin/env node + +const fs = require('fs') +const path = require('path') +const walk = require('walk-sync') +const readFrontmatter = require('../../lib/read-frontmatter') +const csvFile = path.join(process.cwd(), 'shortTitles.csv') +fs.writeFileSync(csvFile, 'Product,Article Title,Short title,Relative path\n') + +const files = walk(path.join(process.cwd(), 'content'), { includeBasePath: true, directories: false }) +files.forEach(file => { + const relativeFilePath = file.replace(process.cwd(), '') + const productName = relativeFilePath.split('/')[2] + + const fileContent = fs.readFileSync(file, 'utf8') + const { data } = readFrontmatter(fileContent) + const { title, shortTitle } = data + + if (title && !shortTitle && title.length > 25) { + fs.appendFileSync(csvFile, `"${productName}","${title}",,${relativeFilePath}\n`) + } +}) diff --git a/script/content-migrations/update-short-titles-from-csv.js b/script/content-migrations/update-short-titles-from-csv.js new file mode 100755 index 000000000000..f5a9b1a8aa8d --- /dev/null +++ b/script/content-migrations/update-short-titles-from-csv.js @@ -0,0 +1,66 @@ +#!/usr/bin/env node + +const fs = require('fs') +const path = require('path') +const readFrontmatter = require('../../lib/read-frontmatter') +const csv = require('csv-parse') +const { exit } = require('process') + +main() + +async function main() { + let fileCounter = 0 + let csvHeader = [] + const csvFileName = 'shortTitles.csv' + const filePath = path.join(process.cwd(), csvFileName) + const reader = fs.createReadStream(filePath) + + // Parse each row of the csv + reader + .pipe(csv()) + .on('data', (csvData) => { + if (csvHeader.length === 0) { + csvHeader = verifyHeader(csvData) + } else { + if (csvData[3] && csvData[4]) { + updateFrontmatter(csvData) + fileCounter++ + } + } + }) + .on('end', () => { + console.log(`⭐ Completed updating the shortTitle frontmatter.\nUpdated ${fileCounter} files.`) + }) +} + +async function updateFrontmatter(csvData) { + + const filePath = path.join(process.cwd(), csvData[4]) + const fileContent = fs.readFileSync(filePath, 'utf8') + const { content, data } = readFrontmatter(fileContent) + data.shortTitle = csvData[3] + const newContents = readFrontmatter.stringify(content, data, { lineWidth: 10000 }) + fs.writeFileSync(filePath, newContents) + +} + +// Ensure the columns being read out are in the location expected +async function verifyHeader(csvData) { + + const csvHeader = [] + + csvData.forEach(element => { + csvHeader.push(element) + }) + + if (csvHeader[3] !== 'Short title') { + console.log(`The CSV headers are malformed. Expected to see column 3 contain the header 'Short title'`) + exit(1) + } + if (csvHeader[4] !== 'Relative path') { + console.log(`The CSV headers are malformed. Expected to see column 4 contain the header 'Relative path'`) + exit(1) + } + + return csvHeader +} \ No newline at end of file