Skip to content

Commit a2cef38

Browse files
committed
Extend ContentModel from ContentModelEntryNode
Completing the first pass of classification
1 parent 9abe08d commit a2cef38

File tree

3 files changed

+148
-127
lines changed

3 files changed

+148
-127
lines changed

src/compiler/contentModel/index.js

Lines changed: 84 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const _ = require('lodash')
33
const frontMatter = require('front-matter')
44
const ImmutableStack = require('../../lib/ImmutableStack')
55
const { removeExtension, isTemplateFile } = require('../../lib/contentModelHelpers')
6+
const ContentModelEntryNode = require('../../lib/ContentModelEntryNode')
67
const matcha = require('../../lib/matcha')
78

89
const models = {
@@ -27,7 +28,7 @@ const parseLink = (value) => {
2728

2829
const findLinkedEntry = (contentModel, link) => {
2930
const collectionSlugRe = new RegExp(link.collectionSlug, 'i')
30-
const collection = contentModel.collections.find(c => c.slug.match(collectionSlugRe))
31+
const collection = contentModel.subtree.collections.find(c => c.slug.match(collectionSlugRe))
3132
let container = collection
3233

3334
for (const categorySlug of link.categorySlugs) {
@@ -88,7 +89,7 @@ const linkBack = (post, entry, key) => {
8889
}
8990

9091
const linkEntries = (contentModel) => {
91-
contentModel.collections.forEach(collection => {
92+
contentModel.subtree.collections.forEach(collection => {
9293
collection.subtree.posts.forEach(post => {
9394
const fields = Object.keys(post)
9495
Object.keys(post).forEach(key => {
@@ -127,7 +128,7 @@ const linkEntries = (contentModel) => {
127128
})
128129
}
129130

130-
const defaultContentModelSettings = {
131+
const defaultSettings = {
131132
permalinkPrefix: '/',
132133
out: resolve('.'),
133134
defaultCategoryName: 'Unclassified',
@@ -141,28 +142,64 @@ const defaultContentModelSettings = {
141142
},
142143
mode: 'start'
143144
}
144-
class ContentModel {
145+
class ContentModel extends ContentModelEntryNode {
145146
static serialize(contentModel) {
146147
return {
147-
homepage: models.Homepage.serialize(contentModel.homepage),
148-
subpages: contentModel.subpages.map(models.Subpage.serialize),
149-
collections: contentModel.collections.map(models.Collection.serialize),
150-
assets: contentModel.assets.map(models.Asset.serialize)
148+
homepage: models.Homepage.serialize(contentModel.subtree.homepage),
149+
subpages: contentModel.subtree.subpages.map(models.Subpage.serialize),
150+
collections: contentModel.subtree.collections.map(models.Collection.serialize),
151+
assets: contentModel.subtree.assets.map(models.Asset.serialize)
151152
}
152153
}
153154

154-
constructor(contentModelSettings = defaultContentModelSettings, contentTypes = []) {
155-
this.settings = {
156-
...defaultContentModelSettings,
155+
static draftCheck(mode, node) {
156+
return mode === 'start' || !node.draft
157+
}
158+
159+
constructor(fsNode, contentModelSettings = defaultSettings, contentTypes) {
160+
const settings = {
161+
...defaultSettings,
157162
...contentModelSettings
158163
}
164+
165+
const context = new ImmutableStack([{
166+
key: 'root',
167+
outputPath: settings.out,
168+
permalink: settings.permalinkPrefix
169+
}])
170+
171+
super(fsNode, context, settings)
172+
159173
this.contentTypes = contentTypes
174+
175+
const collectionAliasesFromContentTypes = contentTypes
176+
.filter(ct => ct.model === 'collection')
177+
.map(ct => ct.collectionAlias)
178+
179+
const collectionAliasesFromFrontMatter = this.collectionAliases || []
180+
181+
this.collectionAliases = [
182+
...collectionAliasesFromContentTypes,
183+
...collectionAliasesFromFrontMatter
184+
]
185+
186+
this.matchers = this.getSubtreeMatchers()
187+
this.subtree = this.parseSubtree()
188+
this.afterEffects()
189+
}
190+
191+
getIndexFile() {
192+
return this.fsNode.find(
193+
matcha.templateFile({
194+
nameOptions: ['root']
195+
})
196+
)
160197
}
161198

162199
getSubtreeMatchers() {
163200
return {
164201
collectionIndexFile: matcha.templateFile({
165-
nameOptions: this.collectionAliases.concat('collection').filter(Boolean)
202+
nameOptions: this.collectionAliases.concat('collection')
166203
}),
167204

168205
collection: matcha.directory({
@@ -202,63 +239,33 @@ class ContentModel {
202239
}
203240
}
204241

205-
draftCheck(node) {
206-
return this.settings.mode === 'start' || !node.draft
207-
}
208-
209-
create(fileSystemTree) {
210-
const indexFileNameOptions = ['root']
211-
212-
const isRootIndexFile = (node) => {
213-
return isTemplateFile(node) && node.name.match(
214-
new RegExp(`^(${indexFileNameOptions.join('|')})\\..+$`)
215-
)
216-
}
217-
218-
const indexFile = fileSystemTree.find(isRootIndexFile)
219-
const indexProps = indexFile ? frontMatter(indexFile.content) : {}
220-
221-
const context = new ImmutableStack([{
222-
key: 'root',
223-
outputPath: this.settings.out,
224-
permalink: this.settings.permalinkPrefix
225-
}])
226-
227-
this.contentModel = {
242+
parseSubtree() {
243+
const tree = {
228244
homepage: new models.Homepage(
229245
{ name: 'index', extension: 'md', content: '' },
230-
context,
246+
this.context,
231247
{ homepageDirectory: this.settings.homepageDirectory }
232248
),
233249
subpages: [],
234250
collections: [],
235251
assets: []
236252
}
237253

238-
this.collectionAliases = [
239-
...this.contentTypes
240-
.filter(ct => ct.model === 'collection')
241-
.map(ct => ct.collectionAlias),
242-
...(indexProps.attributes?.collectionAliases || [])
243-
]
244-
245-
this.matchers = this.getSubtreeMatchers()
246-
247-
fileSystemTree.forEach(node => {
248-
if (isRootIndexFile(node)) {
254+
this.fsNode.forEach(node => {
255+
if (node === this.indexFile) {
249256
return
250257
}
251258

252259
if (this.matchers.homepage(node)) {
253-
this.contentModel.homepage = new models.Homepage(node, context, {
260+
tree.homepage = new models.Homepage(node, this.context, {
254261
homepageDirectory: this.settings.homepageDirectory
255262
})
256263
return
257264
}
258265

259266
if (this.matchers.subpage(node)) {
260-
return this.contentModel.subpages.push(
261-
new models.Subpage(node, context, {
267+
return tree.subpages.push(
268+
new models.Subpage(node, this.context, {
262269
pagesDirectory: this.settings.pagesDirectory
263270
})
264271
)
@@ -267,14 +274,14 @@ class ContentModel {
267274
if (this.matchers.pagesDirectory(node)) {
268275
return node.children.forEach(childNode => {
269276
if (this.matchers.subpage(childNode)) {
270-
this.contentModel.subpages.push(
271-
new models.Subpage(childNode, context, {
277+
tree.subpages.push(
278+
new models.Subpage(childNode, this.context, {
272279
pagesDirectory: this.settings.pagesDirectory
273280
})
274281
)
275282
} else if (this.matchers.asset(childNode)) {
276-
this.contentModel.assets.push(
277-
new models.Asset(childNode, context, {
283+
tree.assets.push(
284+
new models.Asset(childNode, this.context, {
278285
assetsDirectory: this.settings.assetsDirectory
279286
})
280287
)
@@ -291,7 +298,7 @@ class ContentModel {
291298
return ct.collectionAlias === (indexFile ? removeExtension(indexFile.name) : node.name)
292299
})
293300

294-
const collection = new models.Collection(node, context, {
301+
const collection = new models.Collection(node, this.context, {
295302
defaultCategoryName: this.settings.defaultCategoryName,
296303
collectionAliases: this.collectionAliases,
297304
mode: this.settings.mode,
@@ -301,67 +308,65 @@ class ContentModel {
301308
contentType
302309
})
303310

304-
if (this.draftCheck(collection)) {
305-
this.contentModel.collections.push(collection)
311+
if (ContentModel.draftCheck(this.settings.mode, collection)) {
312+
tree.collections.push(collection)
306313
}
307314
return
308315
}
309316

310317
if (this.matchers.assetsDirectory(node)) {
311-
return this.contentModel.assets.push(
318+
return tree.assets.push(
312319
...node.children.map(childNode => {
313-
return new models.Asset(childNode, context, {
320+
return new models.Asset(childNode, this.context, {
314321
assetsDirectory: this.settings.assetsDirectory
315322
})
316323
})
317324
)
318325
}
319326

320327
if (this.matchers.asset(node)) {
321-
return this.contentModel.assets.push(
322-
new models.Asset(node, context, {
328+
return tree.assets.push(
329+
new models.Asset(node, this.context, {
323330
assetsDirectory: this.settings.assetsDirectory
324331
})
325332
)
326333
}
327334
})
328-
329-
this.afterEffects()
330-
return this.contentModel
335+
return tree
331336
}
332337

333338
afterEffects() {
334-
linkEntries(this.contentModel)
339+
linkEntries(this)
335340

336-
this.contentModel.collections.forEach(collection => {
337-
collection.afterEffects(this.contentModel)
341+
this.subtree.collections.forEach(collection => {
342+
collection.afterEffects(this.subtree)
338343
})
339344

340-
this.contentModel.subpages.forEach(subpage => {
341-
subpage.afterEffects(this.contentModel)
345+
this.subtree.subpages.forEach(subpage => {
346+
subpage.afterEffects(this.subtree)
342347
})
343348

344-
this.contentModel.homepage.afterEffects(this.contentModel)
349+
this.subtree.homepage.afterEffects(this.subtree)
345350

346-
this.contentModel.assets.forEach(asset => {
347-
asset.afterEffects(this.contentModel)
351+
this.subtree.assets.forEach(asset => {
352+
asset.afterEffects(this.subtree)
348353
})
349354
}
350355

351356
render(renderer) {
352357
const renderHomepage = () => {
353-
return this.contentModel.homepage.render(renderer, {
354-
contentModel: ContentModel.serialize(this.contentModel),
358+
return this.subtree.homepage.render(renderer, {
359+
contentModel: ContentModel.serialize(this),
355360
settings: this.settings,
356361
debug: this.settings.debug
357362
})
358363
}
359364

360365
const renderCollections = () => {
361366
return Promise.all(
362-
this.contentModel.collections.map(collection => {
367+
this.subtree.collections.map(collection => {
363368
return collection.render(renderer, {
364-
contentModel: ContentModel.serialize(this.contentModel),
369+
contentModel: ContentModel.serialize(this),
365370
settings: this.settings,
366371
debug: this.settings.debug
367372
})
@@ -371,9 +376,9 @@ class ContentModel {
371376

372377
const renderSubpages = () => {
373378
return Promise.all(
374-
this.contentModel.subpages.map(subpage => {
379+
this.subtree.subpages.map(subpage => {
375380
return subpage.render(renderer, {
376-
contentModel: ContentModel.serialize(this.contentModel),
381+
contentModel: ContentModel.serialize(this),
377382
settings: this.settings,
378383
debug: this.settings.debug
379384
})
@@ -383,7 +388,7 @@ class ContentModel {
383388

384389
const renderAssets = () => {
385390
return Promise.all(
386-
this.contentModel.assets.map(asset => {
391+
this.subtree.assets.map(asset => {
387392
return asset.render(renderer)
388393
})
389394
)

src/compiler/index.js

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,49 @@
1-
const Debug = require('../debug')
1+
const ContentTypes = require('../content-types')
22

33
module.exports = class Compiler {
4-
constructor({ fileSystemParser, contentModel, renderer }) {
5-
this.fileSystemParser = fileSystemParser
6-
this.contentModel = contentModel
7-
this.renderer = renderer
4+
constructor({ FileSystemParser, ContentModel, Renderer, settings, debug }) {
5+
this.FileSystemParser = FileSystemParser
6+
this.ContentModel = ContentModel
7+
this.Renderer = Renderer
8+
this.settings = settings
9+
this.debug = debug
10+
this.logger = {
11+
debug: debug.debugLog
12+
}
813
}
914

1015
async compile() {
11-
Debug.timeStart('compiler')
12-
const fileSystemTree = await this.fileSystemParser.parse()
13-
const contentModel = this.contentModel.create(fileSystemTree)
14-
if (this.contentModel.render) {
15-
await this.renderer.init()
16-
await this.contentModel.render(this.renderer)
16+
if (typeof this.debug === 'object' && this.debug.timeStart) {
17+
this.debug.timeStart('compiler')
18+
}
19+
20+
const fileSystemParser = new this.FileSystemParser(
21+
this.settings.fileSystemParser,
22+
this.logger
23+
)
24+
25+
const fileSystemTree = await fileSystemParser.parse()
26+
27+
const contentTypes = await ContentTypes.init(
28+
this.settings.contentTypes,
29+
this.logger
30+
)
31+
32+
const contentModel = new this.ContentModel(
33+
fileSystemTree,
34+
this.settings.contentModel,
35+
contentTypes
36+
)
37+
38+
if (contentModel.render) {
39+
await this.Renderer.init()
40+
await contentModel.render(this.Renderer)
1741
} else {
18-
await this.renderer.render(contentModel)
42+
await this.Renderer.render(contentModel)
1943
}
20-
Debug.timeEnd('compiler')
44+
45+
this.debug.timeEnd('compiler')
46+
2147
return {
2248
fileSystemTree,
2349
contentModel

0 commit comments

Comments
 (0)