1 | const fs = require('fs')
|
2 | const { join } = require('path')
|
3 | const fm = require('front-matter')
|
4 | const pathToRegexp = require('path-to-regexp')
|
5 | const paramCase = require('param-case')
|
6 |
|
7 | const parser = require('markdown-it')({
|
8 | preset: 'default',
|
9 | html: true
|
10 |
|
11 | })
|
12 |
|
13 | var contentData = {}
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | exports.default = function getContent (options) {
|
20 | const srcPath = join(options.srcPath, options.srcDir)
|
21 |
|
22 | const registeredDirs = !Array.isArray(options.dirs[0])
|
23 | ? [[options.dirs[0]]] : options.dirs
|
24 |
|
25 | registeredDirs.forEach(type => {
|
26 | const dirName = join('/', type[0])
|
27 | const dirOpts = getDirOpts(type[1] || {}, options)
|
28 | const otherDirs = getOtherRegisteredDirs(dirName, registeredDirs)
|
29 | contentData[dirName] = []
|
30 | getFromDir(srcPath, dirName, otherDirs, dirOpts)
|
31 | })
|
32 | return contentData
|
33 | }
|
34 |
|
35 | exports.getContent = function (onlyDir) {
|
36 | return contentData
|
37 | }
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | function getFromDir(srcPath, registeredDir, blacklist, dirOpts) {
|
44 | |
45 |
|
46 |
|
47 | function applyToAllFiles (dir, func, files = []) {
|
48 | const dirPath = join(srcPath, registeredDir, dir)
|
49 | fs.readdirSync(dirPath).forEach(stat => {
|
50 | const statPath = join(dirPath, stat)
|
51 | if(fs.statSync(statPath).isDirectory()) {
|
52 | const nestedDir = join(dir, stat)
|
53 | getFilesData(nestedDir, func, files)
|
54 | } else {
|
55 | const nestedfilePath = join(dir, stat)
|
56 | func(nestedfilePath)
|
57 | }
|
58 | })
|
59 | return files
|
60 | }
|
61 |
|
62 | const dirPath = join(srcPath, registeredDir)
|
63 | fs.readdirSync(dirPath).forEach(stat => {
|
64 | const statPath = join(dirPath, stat)
|
65 | if(fs.statSync(statPath).isDirectory()) {
|
66 | const dirSection = join(registeredDir, stat)
|
67 | if (!(blacklist.indexOf(dirSection) > -1)) {
|
68 | applyToAllFiles(stat, nestedFilePath => {
|
69 | const filePath = join(dirPath, nestedFilePath)
|
70 | contentData[registeredDir].push({
|
71 | src: nestedFilePath,
|
72 | data: getPageData(filePath, registeredDir, dirOpts)
|
73 | })
|
74 | })
|
75 | }
|
76 | } else {
|
77 | contentData[registeredDir].push({
|
78 | src: stat,
|
79 | data: getPageData(statPath, registeredDir, dirOpts)
|
80 | })
|
81 | }
|
82 | })
|
83 |
|
84 | return contentData
|
85 | }
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | function getPageData(filePath, section, dirOpts) {
|
94 | function getUrlData (metadata) {
|
95 | const urlData = {}
|
96 |
|
97 | urlData.fileName = filePath
|
98 | .replace(/^.*[\\\/]/, '')
|
99 | .replace(/(.)[^.]+$/, '')
|
100 |
|
101 | urlData.section = section
|
102 |
|
103 | urlData.slug = paramCase(metadata.slug
|
104 | || urlData.fileName.replace(/!?(\d{4}-\d{2}-\d{2}-)/, ''))
|
105 |
|
106 | if (dirOpts.isPost) {
|
107 | const fileDate = urlData.fileName.match(/!?(\d{4}-\d{2}-\d{2})/)
|
108 | if (!fileDate) throw Error(`Content in "${section}" does not have a date!`)
|
109 |
|
110 | urlData.date = fileDate[0]
|
111 |
|
112 | const dateData = urlData.date.split('-')
|
113 | urlData.year = dateData[0]
|
114 | urlData.month = dateData[1]
|
115 | urlData.day = dateData[2]
|
116 | }
|
117 |
|
118 | const toPath = pathToRegexp.compile(dirOpts.permalink)
|
119 | urlData.permalink = metadata.permalink
|
120 | || toPath(urlData, { pretty: true }).replace(/%2F/gi, "/")
|
121 |
|
122 | return urlData
|
123 | }
|
124 |
|
125 | const source = fs.readFileSync(filePath, 'utf-8')
|
126 | const frontMatter = fm(source)
|
127 |
|
128 | const metadata = frontMatter.attributes
|
129 | const urlData = getUrlData(metadata, dirOpts)
|
130 | const markdown = frontMatter.body
|
131 |
|
132 | const data = Object.assign({}, urlData, metadata, {
|
133 | content: parser.render(markdown)
|
134 | })
|
135 |
|
136 | return data
|
137 | }
|
138 |
|
139 |
|
140 |
|
141 |
|
142 | function getDirOpts (dir, config) {
|
143 | const mergedData = Object.assign({}, config.data, dir.data)
|
144 | const opts = Object.assign({}, config, dir, { data: mergedData })
|
145 |
|
146 | return {
|
147 | permalink: opts.permalink,
|
148 | isPost: !(opts.isPost === false),
|
149 | data: opts.data
|
150 | }
|
151 | }
|
152 |
|
153 |
|
154 |
|
155 |
|
156 | function getOtherRegisteredDirs (currDir, contentTypes) {
|
157 | const dirs = []
|
158 | contentTypes.forEach(type => {
|
159 | const dir = type[0]
|
160 | if (dir !== currDir) dirs.push(join('/' + dir))
|
161 | })
|
162 | return dirs
|
163 | }
|