From 79376bcdd1e01e427e1c54c8aff3f8132e405945 Mon Sep 17 00:00:00 2001 From: Claude Fable 5 Date: Sun, 12 Jul 2026 23:50:16 +0200 Subject: [PATCH] Give wikilinks a relative href in static/public HTML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The content-cache renderer (docToHtml) emitted wikilinks without an href, so on the read-only public page view they rendered as styled but unclickable text. Emit href="" — relative to the current page URL, it resolves to the sibling page under both /public//… and the in-app /p//… version-history preview, without the renderer needing pond context. Slugs are [a-z0-9-], safe as a bare path segment. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1 --- packages/shared/src/editor-schema/html.test.ts | 9 +++++++++ packages/shared/src/editor-schema/html.ts | 12 ++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/shared/src/editor-schema/html.test.ts b/packages/shared/src/editor-schema/html.test.ts index 7e9321b..975d753 100644 --- a/packages/shared/src/editor-schema/html.test.ts +++ b/packages/shared/src/editor-schema/html.test.ts @@ -63,4 +63,13 @@ describe('docToHtml (issue #24)', () => { expect(html).toContain('data-checked="true"'); expect(html).toContain(''); }); + + it('gives wikilinks a relative href so public/static HTML is clickable', () => { + const html = docToHtml(markdownToDoc('See [[api-guide|the API guide]].')); + // Relative slug href resolves to the sibling page under both + // /public//… and /p//… without pond context in the renderer. + expect(html).toContain( + 'the API guide', + ); + }); }); diff --git a/packages/shared/src/editor-schema/html.ts b/packages/shared/src/editor-schema/html.ts index 494a93f..06d01b8 100644 --- a/packages/shared/src/editor-schema/html.ts +++ b/packages/shared/src/editor-schema/html.ts @@ -57,14 +57,18 @@ function renderInline(node: Node): string { const widthAttr = width ? ` width="${width}"` : ''; out += `${alt}`; } else if (child.type.name === 'wikilink') { - // The slug and shown text; live title resolution and navigation happen - // where the pond's pages are known (issue #46) — this is the static - // representation used for the content cache and version history. + // The slug and shown text; live title resolution happens in the editor + // where the pond's pages are known (issue #46). The href is the target + // slug *relative* to the current page URL, so this static HTML links + // correctly from both the public view (`/public//`) and the + // in-app version-history preview (`/p//`) without the + // renderer needing the pond context. Slugs are `[a-z0-9-]`, safe as a + // bare path segment. const slug = escapeHtml(child.attrs.targetSlug as string); const display = child.attrs.displayText as string | null; const text = escapeHtml(display ?? (child.attrs.targetSlug as string)); const displayAttr = display ? ` data-display="${escapeHtml(display)}"` : ''; - out += `${text}`; + out += `${text}`; } }); return out;