Skip to content

Commit aa4cbb7

Browse files
committed
[CM2] A collection can render at the root if empty slug
If 'slug:' is added to its frontMatter, its permalink and outputPath will collapse into those of its parent context. When the parent permalink is just '/', child permalinks would break. So, a simple makePermalink helper is used to encapsulate dealing with this case. This helper is used in all models, with the idea of turning any page into a homepage by using the slug: technique. But this is not implemented in models beyond collection, as it'd take more (and ugly) work. If turning any entry or index page into a homepage using the slug technique worked easily, it could work behind the scenes of a 'homepage' frontMatter property. But maybe later. Anyway, rendering a collection in the root is especially helpful for sites with just one collection. The url scheme will work just like it did with CM1.
1 parent adf8202 commit aa4cbb7

File tree

9 files changed

+51
-29
lines changed

9 files changed

+51
-29
lines changed

src/compiler/contentModel2/helpers.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ const parseArray = (array = []) => {
2727
array
2828
}
2929

30+
const makePermalink = (...parts) => {
31+
if (parts[0] === '/') {
32+
return parts[0] + parts.slice(1).join('/')
33+
}
34+
return parts.join('/')
35+
}
36+
3037
const Markdown = {
3138
parse(text) {
3239
return Markdown.unescapeHandlebarsExpressions(
@@ -52,5 +59,6 @@ module.exports = {
5259
isTemplateFile,
5360
removeExtension,
5461
parseArray,
62+
makePermalink,
5563
Markdown
5664
}

src/compiler/contentModel2/index.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,14 @@ class ContentModel {
223223
)
224224
}
225225

226-
return Promise.all([
227-
renderHomepage(),
228-
renderCollections(),
229-
renderSubpages(),
230-
renderAssets()
231-
])
226+
return renderHomepage()
227+
.then(() =>
228+
Promise.all([
229+
renderCollections(),
230+
renderSubpages(),
231+
renderAssets()
232+
])
233+
)
232234
}
233235
}
234236

src/compiler/contentModel2/models/asset.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const { join, resolve } = require('path')
2+
const { makePermalink } = require('../helpers')
23

34
const defaultSettings = {
45
assetsDirectory: 'assets'
@@ -20,9 +21,10 @@ module.exports = function Asset(settings = defaultSettings) {
2021
matchAssetsDirectory: isAssetsDirectory,
2122

2223
create: (node, context) => {
23-
const permalink = (
24-
context.peek().permalink +
25-
[settings.assetsDirectory, node.name].join('/')
24+
const permalink = makePermalink(
25+
context.peek().permalink,
26+
settings.assetsDirectory,
27+
node.name
2628
)
2729

2830
const outputPath = join(

src/compiler/contentModel2/models/attachment.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
const { join } = require('path')
22
const _ = require('lodash')
3+
const { makePermalink } = require('../helpers')
34

45
module.exports = function Attachment() {
56
return {
67
match: node => true,
78

89
create(node, context) {
9-
const permalink = _.compact([
10-
context.peek()?.permalink,
11-
node.name
12-
]).join('/')
10+
const permalink = makePermalink(
11+
..._.compact([
12+
context.peek()?.permalink,
13+
node.name
14+
])
15+
)
1316

1417
const outputPath = join(
1518
..._.compact([

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const { join } = require('path')
22
const frontMatter = require('front-matter')
33
const makeSlug = require('slug')
4-
const { isTemplateFile, Markdown } = require('../../helpers')
4+
const { isTemplateFile, Markdown, makePermalink } = require('../../helpers')
55
const models = {
66
post: require('./post'),
77
attachment: require('../attachment')
@@ -78,7 +78,7 @@ module.exports = function Category(settings = defaultSettings, level = 1) {
7878
contentRaw: '',
7979
slug,
8080
title,
81-
permalink: [context.peek().permalink, slug].join('/'),
81+
permalink: makePermalink(context.peek().permalink, slug),
8282
outputPath: join(context.peek().outputPath, slug),
8383
isDefaultCategory: true,
8484
posts: [],
@@ -103,7 +103,7 @@ module.exports = function Category(settings = defaultSettings, level = 1) {
103103
const indexProps = indexFile ? frontMatter(indexFile.content) : {}
104104

105105
const slug = indexProps.attributes?.slug || makeSlug(node.name)
106-
const permalink = [context.peek().permalink, slug].join('/')
106+
const permalink = makePermalink(context.peek().permalink, slug)
107107
const outputPath = join(context.peek().outputPath, slug)
108108

109109
const categoryContext = {

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ const { join, resolve } = require('path')
22
const _ = require('lodash')
33
const frontMatter = require('front-matter')
44
const makeSlug = require('slug')
5-
const { isTemplateFile, removeExtension, Markdown } = require('../../helpers')
5+
const {
6+
isTemplateFile,
7+
removeExtension,
8+
makePermalink,
9+
Markdown
10+
} = require('../../helpers')
611
const models = {
712
attachment: require('../attachment'),
813
category: require('./category'),
@@ -96,8 +101,10 @@ module.exports = function Collection(settings = defaultSettings, contentTypes =
96101
.filter(ct => ct.model === 'collection')
97102
.find(ct => ct.collectionAlias === indexFileName)
98103

99-
const slug = indexProps.attributes?.slug || makeSlug(node.name)
100-
const permalink = context.peek().permalink + slug
104+
const slug = indexProps.attributes?.slug === null ?
105+
'' :
106+
indexProps.attributes?.slug || makeSlug(node.name)
107+
const permalink = makePermalink(context.peek().permalink, slug)
101108
const outputPath = join(context.peek().outputPath, slug)
102109
const collectionContext = {
103110
...indexProps.attributes,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const { join } = require('path')
2-
const { isTemplateFile, parseArray } = require('../../helpers')
2+
const { isTemplateFile, parseArray, makePermalink } = require('../../helpers')
33
const models = {
44
_baseEntry: require('../_baseEntry'),
55
attachment: require('../attachment'),
@@ -29,10 +29,10 @@ module.exports = function Post(settings = defaultSettings) {
2929
create: (node, context) => {
3030
const baseEntryProps = models._baseEntry(node, indexFileNameOptions)
3131

32-
const permalink = [
32+
const permalink = makePermalink(
3333
context.peek().permalink,
3434
baseEntryProps.slug
35-
].join('/') + (node.children ? '' : '.html')
35+
) + (node.children ? '' : '.html')
3636

3737
const outputPath = join(context.peek().outputPath, baseEntryProps.slug)
3838

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
const { join } = require('path')
22
const makeSlug = require('slug')
3+
const { makePermalink } = require('../../helpers')
34

45
module.exports = function Tag() {
56
return {
67
create: (name, context) => {
78
const slug = makeSlug(name)
8-
const permalink = [context.peek().permalink, 'tags', slug].join('/')
9+
const permalink = makePermalink(context.peek().permalink, 'tags', slug)
910
const outputPath = join(context.peek().outputPath, 'tags', slug)
1011
return {
1112
name,

src/compiler/contentModel2/models/subpage.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const { join, resolve } = require('path')
2-
const { isTemplateFile } = require('../helpers')
2+
const { isTemplateFile, makePermalink } = require('../helpers')
33
const models = {
44
_baseEntry: require('./_baseEntry'),
55
attachment: require('./attachment'),
@@ -41,11 +41,10 @@ module.exports = function Subpage(settings = defaultSettings) {
4141
create: (node, context) => {
4242
const baseEntryProps = models._baseEntry(node, indexFileNameOptions)
4343

44-
const permalink = (
45-
context.peek().permalink +
46-
baseEntryProps.slug +
47-
(baseEntryProps.hasIndex ? '' : '.html')
48-
)
44+
const permalink = makePermalink(
45+
context.peek().permalink,
46+
baseEntryProps.slug
47+
) + (baseEntryProps.hasIndex ? '' : '.html')
4948

5049
const outputPath = join(
5150
context.peek().outputPath,

0 commit comments

Comments
 (0)