Skip to content

Commit

Permalink
Deprecates file.path in favor of file.permalink and adds better testing
Browse files Browse the repository at this point in the history
  • Loading branch information
webketje committed Jan 3, 2023
1 parent b6ee083 commit c7a56f1
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 26 deletions.
6 changes: 5 additions & 1 deletion lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export type Options = {
*/
date?: string;
/**
* _**[DEPRECATED]** - _will be defaulted to false and removed in the next major version_. When `true` (by default), will duplicate sibling files so relative links keep working in resulting structure. Turn off by setting `false`. Can also be set to `folder`, which uses a strategy that considers files in folder as siblings if the folder is named after the html file.
* **[DEPRECATED]** - _will be defaulted to false and removed in the next major version_. When `true` (by default), will duplicate sibling files so relative links keep working in resulting structure. Turn off by setting `false`. Can also be set to `folder`, which uses a strategy that considers files in folder as siblings if the folder is named after the html file.
*/
relative?: boolean | 'folder';
/**
Expand All @@ -86,6 +86,10 @@ export type Options = {
* Basename of the permalinked file (default: `index.html`)
*/
directoryIndex?: string;
/**
* Whether a trailing `/` should be added to the `file.permalink` property. Useful to avoid redirects on servers which do not have a built-in rewrite module enabled.
*/
trailingSlash?: boolean;
/**
* **[DEPRECATED]** - _use `duplicates` option instead_. Set to `true` to add a number to duplicate permalinks (default: `false`), or specify a custom duplicate handling callback of the form `(permalink, files, file, options) => string`
*/
Expand Down
9 changes: 7 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const dupeHandlers = {
* @property {boolean|'folder'} [relative=true] _**[DEPRECATED]** - _will be defaulted to false and removed in the next major version_. When `true` (by default), will duplicate sibling files so relative links keep working in resulting structure. Turn off by setting `false`. Can also be set to `folder`, which uses a strategy that considers files in folder as siblings if the folder is named after the html file.
* @property {string} [indexFile='index.html'] _**[DEPRECATED]** - _renamed to directoryIndex_. Basename of the permalinked file (default: `index.html`)
* @property {string} [directoryIndex='index.html'] Basename of the permalinked file (default: `index.html`)
* @property {boolean} [trailingSlash=false] Whether a trailing `/` should be added to the `file.permalink` property. Useful to avoid redirects on servers which do not have a built-in rewrite module enabled.
* @property {boolean|Function} [unique] **[DEPRECATED]** - _use `duplicates` option instead_. Set to `true` to add a number to duplicate permalinks (default: `false`), or specify a custom duplicate handling callback of the form `(permalink, files, file, options) => string`
* @property {boolean} [duplicatesFail=false] **[DEPRECATED]** - _use `duplicates` option instead_. Set to `true` to throw an error if multiple file path transforms result in the same permalink. `false` by default
* @property {'error'|'index'|'overwrite'|Function} [duplicates] How to handle duplicate target URI's.
Expand All @@ -81,6 +82,7 @@ const defaultOptions = {
slug: { lower: true },
relative: true,
indexFile: 'index.html',
trailingSlash: false,
unique: false,
duplicatesFail: false,
linksets: []
Expand Down Expand Up @@ -180,8 +182,6 @@ const normalizeOptions = (options) => {
}
} else if (Object.keys(dupeHandlers).includes(options.duplicates)) {
options.duplicates = dupeHandlers[options.duplicates]
} else {
options.duplicates = dupeHandlers.overwrite
}

if (options.indexFile && !options.directoryIndex) {
Expand Down Expand Up @@ -406,6 +406,10 @@ function permalinks(options) {

// add to permalink data for use in links in templates
let permalink = ppath === '.' ? '' : ppath.replace(/\\/g, '/')
if (options.trailingSlash) {
permalink = path.posix.join(permalink, './')
}
// contrary to the 2.x "path" property, the permalink property does not override previously set file metadata
if (!data.permalink) {
data.permalink = permalink
}
Expand All @@ -419,6 +423,7 @@ function permalinks(options) {
return permalink
},
set(value) {
/* istanbul ignore next */
permalink = value
}
})
Expand Down
101 changes: 78 additions & 23 deletions test/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -317,32 +317,87 @@ describe('@metalsmith/permalinks', () => {
})
})

it('should set a permalink property on each processed file', done => {
const ms = Metalsmith(path.join(fixturesBase, 'no-relative'))
.env('DEBUG', process.env.DEBUG)
.ignore('**')
describe('sets a file.permalink property', () => {
let ms
beforeEach(() => {
ms = Metalsmith(path.join(fixturesBase, 'no-relative'))
.env('DEBUG', process.env.DEBUG)
.ignore('**')
})

const files = {
'test.html': {
contents: Buffer.from('Test'),
path: 'test.html'
},
[path.join('nested', 'test.html')]: {
contents: Buffer.from('Nested test')
it('on each processed file', done => {
const files = {
'test.html': {
contents: Buffer.from('Test'),
path: 'test.html'
},
[path.join('nested', 'test.html')]: {
contents: Buffer.from('Nested test')
}
}
}

permalinks()(files, ms, (err) => {
if (err) done(err)
assert.deepStrictEqual(Object.values(files).map(f => f.permalink).sort(), [
'nested/test',
'test',
])
assert.deepStrictEqual(Object.keys(files).sort(), [
'nested/test/index.html',
'test/index.html',
].map(path.normalize))
done()
permalinks()(files, ms, (err) => {
if (err) done(err)
assert.deepStrictEqual(Object.values(files).map(f => f.permalink).sort(), [
'nested/test',
'test',
])
assert.deepStrictEqual(Object.keys(files).sort(), [
'nested/test/index.html',
'test/index.html',
].map(path.normalize))
done()
})
})

it('that supports adding a trailing slash to the permalink property', done => {
const ms = Metalsmith(path.join(fixturesBase, 'no-relative'))
.env('DEBUG', process.env.DEBUG)
.ignore('**')

const files = {
'test.html': {
contents: Buffer.from('Test'),
},
[path.join('nested', 'test.html')]: {
contents: Buffer.from('Nested test')
}
}

permalinks({
trailingSlash: true
})(files, ms, (err) => {
if (err) done(err)
assert.deepStrictEqual(Object.values(files).map(f => f.permalink).sort(), [
'nested/test/',
'test/',
])
assert.deepStrictEqual(Object.keys(files).sort(), [
'nested/test/index.html',
'test/index.html',
].map(path.normalize))
done()
})
})

it('but without overriding explicitly defined permalinks', done => {
const files = {
'test.html': {
contents: Buffer.from('Test'),
title: 'HelloWorld',
permalink: 'new/permalink/hehe'
}
}

permalinks({
trailingSlash: true,
pattern: ':title'
})(files, ms, (err) => {
if (err) done(err)
assert.strictEqual(Object.values(files)[0].permalink, 'new/permalink/hehe')
assert.strictEqual(Object.keys(files)[0], path.normalize('new/permalink/hehe/index.html'))
done()
})
})
})
})

0 comments on commit c7a56f1

Please sign in to comment.