Skip to content

Commit c415e24

Browse files
committed
Fixes #135 and also removes some warnings that logged when they shouldn't
1 parent c7a1436 commit c415e24

File tree

4 files changed

+61
-47
lines changed

4 files changed

+61
-47
lines changed

src/index.js

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const dupeHandlers = {
2424
return target
2525
},
2626
overwrite(targetPath, filesObj, filename, opts) {
27-
return path.join(targetPath, opts.directoryIndex)
27+
return path.join(targetPath || '', opts.directoryIndex)
2828
}
2929
}
3030

@@ -77,24 +77,13 @@ const dupeHandlers = {
7777

7878
/** @type {Options} */
7979
const defaultOptions = {
80-
pattern: null,
8180
date: 'YYYY/MM/DD',
8281
slug: { lower: true },
8382
relative: true,
84-
indexFile: 'index.html',
8583
trailingSlash: false,
86-
unique: false,
87-
duplicatesFail: false,
8884
linksets: []
8985
}
9086

91-
const defaultLinkset = {
92-
date: 'YYYY/MM/DD',
93-
slug: { lower: true },
94-
relative: true,
95-
isDefault: false
96-
}
97-
9887
/**
9988
* Maps the slugify function to slug to maintain compatibility
10089
*
@@ -104,7 +93,7 @@ const defaultLinkset = {
10493
* @return {String}
10594
*/
10695
function slugFn(options = defaultOptions.slug) {
107-
return (text) => {
96+
return function defaultSlugFn(text) {
10897
if (typeof options.extend === 'object' && options.extend !== null) {
10998
slugify.extend(options.extend)
11099
}
@@ -146,15 +135,6 @@ const html = (str) => path.extname(str) === '.html'
146135
*/
147136
const format = (string) => (date) => moment(date).utc().format(string)
148137

149-
const normalizeLinkset = (linkset) => {
150-
linkset = Object.assign({}, defaultLinkset, linkset)
151-
linkset.date = format(linkset.date)
152-
if (typeof linkset.slug !== 'function') {
153-
linkset.slug = slugFn(linkset.slug)
154-
}
155-
return linkset
156-
}
157-
158138
/**
159139
* Normalize an options argument.
160140
*
@@ -165,10 +145,7 @@ const normalizeOptions = (options) => {
165145
if (typeof options === 'string') {
166146
options = { pattern: options }
167147
}
168-
options = normalizeLinkset(Object.assign({}, defaultOptions, options))
169-
if (Array.isArray(options.linksets)) {
170-
options.linksets = options.linksets.map(normalizeLinkset)
171-
}
148+
options = Object.assign({}, defaultOptions, options)
172149

173150
if (!options.duplicates) {
174151
if (options.duplicatesFail) {
@@ -184,10 +161,17 @@ const normalizeOptions = (options) => {
184161
options.duplicates = dupeHandlers[options.duplicates]
185162
}
186163

187-
if (options.indexFile && !options.directoryIndex) {
188-
options.directoryIndex = options.indexFile
164+
if (!options.directoryIndex) {
165+
if (options.indexFile) {
166+
options.directoryIndex = options.indexFile
167+
} else {
168+
options.directoryIndex = 'index.html'
169+
}
189170
}
190171

172+
options.slug = typeof options.slug === 'function' ? options.slug : slugFn(options.slug)
173+
options.date = format(options.date)
174+
191175
return options
192176
}
193177

@@ -316,21 +300,16 @@ const replace = (pattern, data, options) => {
316300
* @returns {import('metalsmith').Plugin}
317301
*/
318302
function permalinks(options) {
319-
options = normalizeOptions(options)
303+
const normalizedOptions = normalizeOptions(options)
320304

321-
const { linksets } = options
322-
let defaultLinkset = linksets.find((ls) => {
323-
return Boolean(ls.isDefault)
324-
})
325-
326-
if (!defaultLinkset) {
327-
defaultLinkset = options
305+
let primaryLinkset = normalizedOptions.linksets.find((ls) => Boolean(ls.isDefault))
306+
if (!primaryLinkset) {
307+
primaryLinkset = normalizedOptions
328308
}
329309

330310
const dupes = {}
331-
332311
const findLinkset = (file) => {
333-
const set = linksets.find((ls) =>
312+
const set = normalizedOptions.linksets.find((ls) =>
334313
Object.keys(ls.match).some((key) => {
335314
if (file[key] === ls.match[key]) {
336315
return true
@@ -340,14 +319,15 @@ function permalinks(options) {
340319
}
341320
})
342321
)
343-
return set || defaultLinkset
322+
323+
return set ? set : primaryLinkset
344324
}
345325

346326
return function permalinks(files, metalsmith, done) {
347327
const debug = metalsmith.debug('@metalsmith/permalinks')
348-
debug.info('Running with options: %O', options)
328+
debug.info('Running with options: %O', normalizedOptions)
349329

350-
if (options.relative || options.linksets.find((ls) => ls.relative)) {
330+
if (normalizedOptions.relative || normalizedOptions.linksets.find((ls) => ls.relative)) {
351331
debug.warn(
352332
'The relative option is deprecated and its default value will be changed to false before being removed in the next major versions.'
353333
)
@@ -356,8 +336,8 @@ function permalinks(options) {
356336
)
357337
}
358338

359-
const makeUnique = options.duplicates
360-
const map = new Map(Object.entries(options))
339+
const makeUnique = normalizedOptions.duplicates
340+
const map = new Map(Object.entries(normalizedOptions))
361341
/* istanbul ignore next */
362342
if (map.has('duplicatesFail') || map.has('unique')) {
363343
debug.warn(
@@ -375,7 +355,21 @@ function permalinks(options) {
375355

376356
debug('applying pattern: %s to file: %s', linkset.pattern, file)
377357

378-
let ppath = replace(linkset.pattern, data, linkset) || resolve(file, options.directoryIndex)
358+
const opts =
359+
linkset === primaryLinkset
360+
? primaryLinkset
361+
: {
362+
...linkset,
363+
directoryIndex: normalizedOptions.directoryIndex,
364+
slug:
365+
typeof linkset.slug === 'function'
366+
? linkset.slug
367+
: typeof linkset.slug === 'object'
368+
? slugFn(linkset.slug)
369+
: normalizedOptions.slug,
370+
date: typeof linkset.date === 'string' ? format(linkset.date) : normalizedOptions.date
371+
}
372+
let ppath = replace(linkset.pattern, data, opts) || resolve(file, normalizedOptions.directoryIndex)
379373

380374
let fam
381375
switch (linkset.relative) {
@@ -394,7 +388,7 @@ function permalinks(options) {
394388
ppath = data.permalink
395389
}
396390

397-
const out = makeUnique(path.normalize(ppath), files, file, options)
391+
const out = makeUnique(path.normalize(ppath), files, file, normalizedOptions)
398392
if (out instanceof Error) {
399393
return done(out)
400394
}
@@ -413,7 +407,7 @@ function permalinks(options) {
413407

414408
// add to permalink data for use in links in templates
415409
let permalink = ppath === '.' ? '' : ppath.replace(/\\/g, '/')
416-
if (options.trailingSlash) {
410+
if (normalizedOptions.trailingSlash) {
417411
permalink = path.posix.join(permalink, './')
418412
}
419413
// contrary to the 2.x "path" property, the permalink property does not override previously set file metadata

test/fixtures/slug-custom-function-linksets/expected/blog/post15/index.html

Whitespace-only changes.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: post1
3+
collection: blog
4+
---

test/index.cjs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,22 @@ const fixtures = [
141141
slug: transliteration.slugify
142142
}
143143
},
144+
{
145+
message: 'should use custom slug function for linksets too',
146+
folder: 'slug-custom-function-linksets',
147+
options: {
148+
relative: false,
149+
slug(str) {
150+
return str + str.length
151+
},
152+
linksets: [
153+
{
154+
match: { collection: 'blog' },
155+
pattern: 'blog/:title'
156+
}
157+
]
158+
}
159+
},
144160
{
145161
message: 'should accept options for slug module',
146162
folder: 'slug-options',
@@ -247,7 +263,7 @@ describe('@metalsmith/permalinks', () => {
247263
.env('DEBUG', process.env.DEBUG)
248264
.use(permalinks(options))
249265
.build((err) => {
250-
if (err) done(err)
266+
if (err) return done(err)
251267
try {
252268
equal(path.join(basePath, 'expected'), path.join(basePath, 'build'))
253269
done()

0 commit comments

Comments
 (0)