Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

move-category-to-product.js 4.6 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  1. #!/usr/bin/env node
  2. const assert = require('assert')
  3. const fs = require('fs')
  4. const path = require('path')
  5. const walk = require('walk-sync')
  6. const { execSync } = require('child_process')
  7. const matter = require('gray-matter')
  8. const addRedirectToFrontmatter = require('../lib/redirects/add-redirect-to-frontmatter')
  9. const contentDir = path.join(__dirname, '../content')
  10. // [start-readme]
  11. //
  12. // Pass this script three arguments:
  13. // 1. current category path (e.g., `github/automating-your-workflows-with-github-actions`)
  14. // 2. new product ID (e.g., `actions`)
  15. // 3. new product name in quotes (e.g., `"GitHub Actions"`)
  16. // and it does everything that needs to be done to make the category into a new product.
  17. //
  18. // [end-readme]
  19. // derive global values
  20. const [relativePath, productId, productName] = process.argv.slice(2)
  21. assert(relativePath, 'first arg must be a path to an existing category, e.g., github/working-with-github-pages')
  22. assert(productId, 'second arg must be the ID of the new product, e.g., pages')
  23. assert(productName, 'third arg must be the full name of the new product in quotes, e.g., "GitHub Pages"')
  24. assert.strictEqual(relativePath.split('/').length, 2, 'first arg must only contain one slash, e.g., github/working-with-github-pages')
  25. const oldCategoryDir = path.join(contentDir, relativePath)
  26. assert(fs.existsSync(oldCategoryDir), `directory does not exist: ${oldCategoryDir}`)
  27. const productDir = path.join(contentDir, productId)
  28. const [oldproductId, categoryName] = relativePath.split('/')
  29. // do all the moving/renaming/updating
  30. makeNewProductDir()
  31. moveFilesToNewDir()
  32. createNewProductToc()
  33. removeCategoryFromOldProductToc()
  34. updateFrontmatter()
  35. console.log(`Moved files to content/${productId} and updated frontmatter!\n\nNext steps:\n`)
  36. // display data that needs to be manually added to lib files
  37. printProductsModuleUpdate()
  38. printFrontmatterSchemaUpdate()
  39. function makeNewProductDir () {
  40. if (!fs.existsSync(productDir)) {
  41. execSync(`mkdir ${productDir}`)
  42. }
  43. }
  44. function moveFilesToNewDir () {
  45. execSync(`git mv ${oldCategoryDir} ${productDir}`)
  46. }
  47. function createNewProductToc () {
  48. const productTocPath = path.join(productDir, 'index.md')
  49. const data = {}
  50. data.title = `${productName} Documentation`
  51. data.productVersions = {}
  52. data.productVersions[productId] = '*'
  53. const content = `\n{% link_with_intro /${categoryName} %}`
  54. fs.writeFileSync(productTocPath, matter.stringify(content, data, { lineWidth: 10000 }))
  55. }
  56. function removeCategoryFromOldProductToc () {
  57. const oldProductTocPath = path.join(contentDir, oldproductId, 'index.md')
  58. const tocContents = fs.readFileSync(oldProductTocPath, 'utf8')
  59. const { content, data } = matter(tocContents)
  60. const link = `(\n<!-- if page.version.*? -->)?\n{% link_in_list /${categoryName} %}\n(<!-- endif -->)?`
  61. const newContent = content.replace(new RegExp(link), '')
  62. fs.writeFileSync(oldProductTocPath, matter.stringify(newContent, data, { lineWidth: 10000 }))
  63. }
  64. function updateFrontmatter () {
  65. const newCategoryDir = path.join(productDir, categoryName)
  66. // for every article in the category, update productVersions and redirect frontmatter
  67. walk(newCategoryDir, { includeBasePath: true }).forEach(file => {
  68. const articleContents = fs.readFileSync(file, 'utf8')
  69. const { content, data } = matter(articleContents)
  70. const baseFilename = file.endsWith('index.md') ? '' : path.basename(file, '.md')
  71. const redirectString = path.join('/', oldproductId, categoryName, baseFilename)
  72. data.redirect_from = addRedirectToFrontmatter(data.redirect_from, redirectString)
  73. data.productVersions = {}
  74. data.productVersions[productId] = '*'
  75. const newContents = matter.stringify(content, data, { lineWidth: 10000 })
  76. fs.writeFileSync(file, newContents)
  77. })
  78. }
  79. function printProductsModuleUpdate () {
  80. const newProduct = {
  81. id: productId,
  82. name: productName,
  83. href: path.join('/', productId),
  84. dir: path.join('content/', productId),
  85. toc: path.join('content/', productId, 'index.md')
  86. }
  87. const obj = {}
  88. obj[productId] = newProduct
  89. console.log('1. Add the following block to lib/products.js. Note: the order of this file determines the product order everywhere on the site.\n')
  90. console.log(obj)
  91. }
  92. function printFrontmatterSchemaUpdate () {
  93. const newFrontmatter = {
  94. type: 'string',
  95. conform: '(add validSemverRange here)',
  96. message: 'Must be a valid SemVer range'
  97. }
  98. const obj = {}
  99. obj[productId] = newFrontmatter
  100. console.log('\n2. Add the following block to the productVersions object in lib/frontmatter.js (ordered alphabetically). Make sure the \'conform\' property looks like the others. \n')
  101. console.log(obj)
  102. }
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...