diff --git a/src/helpers/filetreeUtils.js b/src/helpers/filetreeUtils.js index c098c4e62..493dd92e8 100644 --- a/src/helpers/filetreeUtils.js +++ b/src/helpers/filetreeUtils.js @@ -130,7 +130,14 @@ function getPermalinkMeta(note, key) { folders = []; // Handle unexpected cases gracefully } } - folders[folders.length - 1]+= ".md"; + // Path rewrite rules produce a dg-path that already includes the ".md" + // extension (e.g. "Path Rewriting/note.md" -> "note.md"). Strip it before + // re-appending so we don't end up with a double extension ("note.md.md"), + // which would prevent the stem-based navigation ordering from matching. + const lastFolder = folders[folders.length - 1]; + folders[folders.length - 1] = + (lastFolder.endsWith(".md") ? lastFolder.slice(0, -3) : lastFolder) + + ".md"; } catch { //ignore } @@ -139,9 +146,9 @@ function getPermalinkMeta(note, key) { } function assignNested(obj, keyPath, value) { - lastKeyIndex = keyPath.length - 1; - for (var i = 0; i < lastKeyIndex; ++i) { - key = keyPath[i]; + const lastKeyIndex = keyPath.length - 1; + for (let i = 0; i < lastKeyIndex; ++i) { + const key = keyPath[i]; if (!(key in obj)) { obj[key] = { isFolder: true }; } diff --git a/src/helpers/filetreeUtils.test.js b/src/helpers/filetreeUtils.test.js index cdc48fc15..03329044d 100644 --- a/src/helpers/filetreeUtils.test.js +++ b/src/helpers/filetreeUtils.test.js @@ -1,4 +1,5 @@ -const { getFileTree } = require("./filetreeUtils"); +import { describe, it, expect } from "vitest"; +import { getFileTree } from "./filetreeUtils.js"; // Helper to build a minimal note object for testing function makeNote(filePathStem, data = {}) { @@ -149,6 +150,69 @@ describe("filetreeUtils", () => { expect(keys[2]).toBe("beta.md"); }); + it("respects ordering for notes with dg-path from rewrite rules (.md extension)", () => { + // Path rewrite rules produce a dg-path that includes the ".md" extension + // (e.g. "Path Rewriting/note.md" -> dg-path "note.md"). The navigation + // ordering stored by the plugin uses stems without the extension. + const data = { + collections: { + note: [ + makeNote("/zebra", { "dg-path": "zebra.md" }), + makeNote("/alpha", { "dg-path": "alpha.md" }), + makeNote("/beta", { "dg-path": "beta.md" }), + ], + }, + navigationOrder: { + "/": ["beta", "zebra", "alpha"], + }, + }; + + const tree = getFileTree(data); + const keys = Object.keys(tree); + + expect(keys[0]).toBe("beta.md"); + expect(keys[1]).toBe("zebra.md"); + expect(keys[2]).toBe("alpha.md"); + }); + + it("respects ordering for nested folders from rewrite rules (.md extension)", () => { + const data = { + collections: { + note: [ + makeNote("/old/zebra", { "dg-path": "renamed/zebra.md" }), + makeNote("/old/alpha", { "dg-path": "renamed/alpha.md" }), + makeNote("/old/middle", { "dg-path": "renamed/middle.md" }), + ], + }, + navigationOrder: { + "/renamed": ["middle", "zebra", "alpha"], + }, + }; + + const tree = getFileTree(data); + const folderKeys = Object.keys(tree["renamed"]).filter( + (k) => k !== "isFolder" + ); + + expect(folderKeys[0]).toBe("middle.md"); + expect(folderKeys[1]).toBe("zebra.md"); + expect(folderKeys[2]).toBe("alpha.md"); + }); + + it("preserves dots in note names that are not the .md extension", () => { + const data = { + collections: { + note: [makeNote("/my-note-v1.2", { "dg-path": "my-note-v1.2" })], + }, + }; + + const tree = getFileTree(data); + const keys = Object.keys(tree); + + // The dot in "v1.2" must not be treated as an extension boundary + expect(keys).toEqual(["my-note-v1.2.md"]); + }); + it("falls back to default sort when navigationOrder is empty object", () => { const data = { collections: {