Repository navigation
Conversation
…ode) Relative Markdown links currently always resolve with page-as-folder semantics. Wikis authored outside LeafWiki (editors, Git pipelines, generators) use filesystem-relative links, which then break. Add --relative-link-mode=page-folder|filesystem (default page-folder, env LEAFWIKI_RELATIVE_LINK_MODE). filesystem resolves relative targets against the page's parent directory, like files on disk. Applies to the server-side link index and the frontend (via /api/config), with tests on both sides.
A resolved link path like docs/accounts/index.md addressed no page: the '.md' tail was never stripped for lookup (despite the README) and a section's index.md routes as the section itself, so '.../index' is never a real page route. Canonicalize resolved targets on both the server (canonicalPagePath) and the UI (canonicalWikiPageRoute): strip a trailing '.md', then map a trailing 'index' segment to the section route. Makes filesystem-relative wikis (accounts/index.md links) and plain .md links resolve.
…mselves A section's index.md lives IN its folder, so relative links from a section page (e.g. 'usage.md' on wiki/tools/index.md) must resolve against the section route itself, not its parent. Decide the base directory via the tree (kind == section) in filesystem mode; the UI mirrors this with a currentIsSection flag. Refactor engine keeps the simplified parent-strip (opt-in feature, noted for follow-up).
NewWiki loads the tree and builds the initial link index at construction time, so the mode has to be set before that point, not right before the router is built (a restart without a resync briefly indexed links with the default mode). Also: hoist linkBaseDir out of the per-link loop, unexport the test-only mode getter, document the tree-less resolveURLPath variant (refactor engine), and add a section-aware TestLinkBaseDir.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related issue
Fixes #1057
What changed
Relative Markdown links currently always resolve with page-as-folder semantics, so wikis authored outside LeafWiki (Obsidian vaults, docs-as-code repos — the README's own "good fit") break on import (#1057).
Adds
--relative-link-mode=page-folder|filesystem(defaultpage-folder, fully backward compatible; envLEAFWIKI_RELATIVE_LINK_MODE, surfaced to the frontend viaGET /api/configlikeenableLinkRefactor):filesystemmode: relative targets resolve against the page's parent directory, like files on disk — and against the section itself forindex.mdsection pages (foo/index.mdlives infoo/). Section-ness is decided via the tree (kind == section) on the server, via the page kind in the UI..mdis ignored andX/index(.md)addresses the sectionX— a folder'sindex.mdis the folder's page, so no page ever lives at.../index. This also makes the README's documented.md-ignoring true for the server-side link index (it previously never stripped it).SIGUSR1), which recomputes stored link targets./docs/guidepage-folder(default)filesystem[x](setup)/docs/guide/setup/docs/setup[x](../other)/docs/other/other[x](setup.md)/docs/setup(both modes now)Implementation:
internal/links(RelativeLinkMode, section-awarelinkBaseDir,canonicalPagePath), flag + validator incmd/leafwiki, exposure via/api/config, UI counterpart inlib/wikiPath.ts(resolveWikiLinkPath+canonicalWikiPageRoute) consumed byMarkdownLink.tsxfrom the config store.Known simplifications (happy to address per maintainer preference):
internal/linksrather than DI throughLinkService— kept to avoid threading a param through five call layers; can switch if preferred.--enable-link-refactor) keeps a simplified non-section-aware parent-strip infilesystemmode; natural follow-up.How I tested it
helpers_linkmode_test.go(both modes, section-aware base dir via real tree fixtures, canonical lookup, unknown-mode fallback); full backend suite green (54 packages).wikiPath.test.tsfor both modes, section pages and canonicalization; full frontend suite green (725 tests / 99 files).filesystemmode; remaining 14 are genuine references outside the wiki root. Verified link click-through in the browser and correct link indexing straight from a cold start (wiped link store, restart, no manual resync).Checklist
if featurebranches in shared code (the mode is a single seam: base-dir selection + lookup canonicalization ininternal/links, mirrored in the UI'sresolveWikiLinkPath)npm run formatinui/leafwiki-ui