Skip to content

Commit 4eb8756

Browse files
committed
[CM2] Introduce collection data from json file
If collection has a json file that - has the collection's name and - contains data as an array of objects, then treat each object as a post. For this to happen, the post model implements a new createFromData method which bypasses the baseEntry and directly takes attributes from the data and parses the markdown content by itself. Further possibilities: - Specifying data file name in collection.md
1 parent 08f6963 commit 4eb8756

File tree

2 files changed

+58
-16
lines changed

2 files changed

+58
-16
lines changed

src/compiler/contentModel2/models/collection/index.js

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,19 @@ module.exports = function Collection(settings = defaultSettings, contentTypes =
6262
)
6363
}
6464

65+
const isDataFile = (node, parentNode) => {
66+
return node.name.match(new RegExp(`^${parentNode.name}\\.json$`, 'i'))
67+
}
68+
6569
return {
66-
match: node => node.children?.find(isCollectionIndexFile),
70+
match: node => {
71+
const hasCollectionIndex = node.children?.find(isCollectionIndexFile)
72+
const hasCollectionData = node.children?.find(childNode => isDataFile(childNode, node))
73+
return hasCollectionIndex || hasCollectionData
74+
},
6775

6876
create: (node, context) => {
69-
function addUncategorizedPost(childNode) {
77+
function addUncategorizedPost(childNode, postData) {
7078
let defaultCategory = tree.categories.find(cat => cat.isDefaultCategory)
7179
if (!defaultCategory) {
7280
defaultCategory = childModels.category.create(
@@ -79,16 +87,16 @@ module.exports = function Collection(settings = defaultSettings, contentTypes =
7987
defaultCategory,
8088
['posts', 'context', 'content', 'attachments']
8189
)
82-
const uncategorizedPost = childModels.post.create(
83-
childNode,
84-
context.push({
85-
...collectionContext,
86-
key: 'collection'
87-
}).push({
88-
...defaultCategoryContext,
89-
key: 'category'
90-
})
91-
)
90+
const postContext = context.push({
91+
...collectionContext,
92+
key: 'collection'
93+
}).push({
94+
...defaultCategoryContext,
95+
key: 'category'
96+
})
97+
const uncategorizedPost = childNode ?
98+
childModels.post.create(childNode, postContext) :
99+
childModels.post.createFromData(postData, postContext)
92100
defaultCategory.levelPosts.push(uncategorizedPost)
93101
defaultCategory.posts.push(uncategorizedPost)
94102
defaultCategory.posts.forEach(childModels.category.linkPosts)
@@ -103,12 +111,11 @@ module.exports = function Collection(settings = defaultSettings, contentTypes =
103111
}
104112

105113
const indexFile = node.children.find(isCollectionIndexFile)
106-
const indexProps = frontMatter(indexFile.content)
107-
const indexFileName = removeExtension(indexFile.name)
114+
const indexProps = indexFile ? frontMatter(indexFile.content) : {}
108115

109116
const contentType = contentTypes
110117
.filter(ct => ct.model === 'collection')
111-
.find(ct => ct.collectionAlias === indexFileName)
118+
.find(ct => ct.collectionAlias === (indexFile ? removeExtension(indexFile.name) : node.name))
112119

113120
const slug = indexProps.attributes?.slug === null ?
114121
'' :
@@ -159,6 +166,15 @@ module.exports = function Collection(settings = defaultSettings, contentTypes =
159166
if (isCollectionIndexFile(childNode)) {
160167
return
161168
}
169+
if (isDataFile(childNode, node)) {
170+
const data = JSON.parse(childNode.content)
171+
if (!Array.isArray(data)) {
172+
return console.log('Collection data should be an array of posts', childNode.name)
173+
}
174+
return data.forEach(entry => {
175+
addUncategorizedPost(null, entry)
176+
})
177+
}
162178
if (childModels.post.match(childNode)) {
163179
return addUncategorizedPost(childNode)
164180
}

src/compiler/contentModel2/models/collection/post.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const { join } = require('path')
22
const makeSlug = require('slug')
3-
const { isTemplateFile, makePermalink } = require('../../helpers')
3+
const { isTemplateFile, makePermalink, Markdown } = require('../../helpers')
44
const models = {
55
facet: require('./facet'),
66
_baseEntry: require('../_baseEntry'),
@@ -62,6 +62,32 @@ module.exports = function Post(settings = defaultSettings, contentTypes = []) {
6262
}
6363
},
6464

65+
createFromData: (data, context) => {
66+
const slug = data.slug || makeSlug(data.title)
67+
68+
const postContext = {
69+
title: data.title,
70+
slug,
71+
permalink: makePermalink(context.peek().permalink, slug) + '.html',
72+
outputPath: join(context.peek().outputPath, slug),
73+
}
74+
75+
const contentType = context.peek().entryContentType
76+
const contentRaw = data.content || ''
77+
78+
return {
79+
...data,
80+
...postContext,
81+
context,
82+
contentType,
83+
schema: contentTypes.find(ct => ct.name === contentType),
84+
date: new Date(data.date || Date.now()),
85+
contentRaw,
86+
content: Markdown.parse(contentRaw),
87+
attachments: []
88+
}
89+
},
90+
6591
afterEffects: (contentModel, post, facets) => {
6692
models.facet().linkEntryFieldsToFacets(post, facets)
6793

0 commit comments

Comments
 (0)