diff --git a/lib/build-pages/compute-page-url.js b/lib/build-pages/compute-page-url.js new file mode 100644 index 0000000..94f3f01 --- /dev/null +++ b/lib/build-pages/compute-page-url.js @@ -0,0 +1,17 @@ +import { fsPathToUrlPath } from './page-builders/fs-path-to-url.js' + +/** + * Derive the canonical URL path for a page from its filesystem path and output name. + * Index pages get a trailing-slash URL; other outputs include the filename. + * + * @param {object} params + * @param {string} params.path - The page's directory path relative to src root + * @param {string} params.outputName - The output filename (e.g. 'index.html' or 'loose-md.html') + * @returns {string} + */ +export function computePageUrl ({ path, outputName }) { + if (outputName === 'index.html') { + return path ? fsPathToUrlPath(path) + '/' : '/' + } + return path ? fsPathToUrlPath(path) + '/' + outputName : '/' + outputName +} diff --git a/lib/build-pages/page-data.js b/lib/build-pages/page-data.js index 0cafe0f..af078b9 100644 --- a/lib/build-pages/page-data.js +++ b/lib/build-pages/page-data.js @@ -6,6 +6,7 @@ import { resolveVars, resolvePostVars } from './resolve-vars.js' import { pageBuilders } from './page-builders/index.js' +import { computePageUrl } from './compute-page-url.js' // @ts-expect-error import pretty from 'pretty' @@ -141,6 +142,7 @@ export class PageData { const { globalVars, globalDataVars, pageVars, builderVars } = this // @ts-ignore return { + pageUrl: this.#computePageUrl(), ...globalVars, ...globalDataVars, ...pageVars, @@ -156,6 +158,15 @@ export class PageData { return this.workerFiles } + /** + * Derive the canonical URL path for this page from its filesystem path and output name. + * Index pages get a trailing-slash URL; other outputs include the filename. + * @return {string} + */ + #computePageUrl () { + return computePageUrl(this.pageInfo) + } + /** * [init description] * @param {object} params - Parameters required to initialize diff --git a/lib/build-pages/page-data.test.js b/lib/build-pages/page-data.test.js new file mode 100644 index 0000000..3daf573 --- /dev/null +++ b/lib/build-pages/page-data.test.js @@ -0,0 +1,21 @@ +import { test } from 'node:test' +import assert from 'node:assert' +import { computePageUrl } from './compute-page-url.js' + +test.describe('computePageUrl', () => { + test('root index.html maps to /', () => { + assert.strictEqual(computePageUrl({ path: '', outputName: 'index.html' }), '/') + }) + + test('nested index.html gets a trailing-slash URL', () => { + assert.strictEqual(computePageUrl({ path: 'blog/post', outputName: 'index.html' }), '/blog/post/') + }) + + test('non-index output includes filename in URL', () => { + assert.strictEqual(computePageUrl({ path: 'md-page', outputName: 'loose-md.html' }), '/md-page/loose-md.html') + }) + + test('non-index file at root includes filename only', () => { + assert.strictEqual(computePageUrl({ path: '', outputName: 'robots.txt' }), '/robots.txt') + }) +})