Commit 9df917e73a
9df917e73a67d15adecc3f45976690f6fcd4e47a
parent: 145dec111d
Verified · cmc ci/build: success ci/test: success
cmc <hello@cleberg.net> · 2026-09-28 22:34 UTC
wiki: a link to an existing non-page file resolves to _raw, not the page route
Closes #283
Layout: unified · split
CHANGELOG.org
+4
| @@ -6,6 +6,10 @@ anything beyond "replace the binary and restart" is needed. |
| 6 | |
6 | |
| 7 | * Unreleased |
7 | * Unreleased |
| 8 | |
8 | |
| |
9 | - A wiki link to an existing non-page file (an .svg, .txt, .pdf) now |
| |
10 | resolves to the raw route instead of 404ing against the page route |
| |
11 | (#283). |
| |
12 | |
| 9 | - The new-issue form takes labels, milestone and assignee in one step |
13 | - The new-issue form takes labels, milestone and assignee in one step |
| 10 | for writers; the watch button names watching, muted and default; a |
14 | for writers; the watch button names watching, muted and default; a |
| 11 | Discussion heading sits before comment threads; the build page's |
15 | Discussion heading sits before comment threads; the build page's |
internal/httpd/wiki.go
+9 −1
| @@ -248,8 +248,16 @@ func rewriteWikiLinks(rendered template.HTML, p repoPage, page string, isPage, i |
| 248 | } |
248 | } |
| 249 | continue |
249 | continue |
| 250 | } |
250 | } |
| |
251 | // A plain link is usually to another page, but a link to |
| |
252 | // an existing non-page file (an .svg, .txt, .pdf) must |
| |
253 | // go to _raw the same as an image src, or it 404s |
| |
254 | // against the page route (#283). |
| 251 | if target, ok := wikiResolve(page, trimPageExt(v), isPage); ok { |
255 | if target, ok := wikiResolve(page, trimPageExt(v), isPage); ok { |
| 252 | n.Attr[i].Val = base + "/" + target |
256 | if raw, rok := wikiResolve(page, v, isFile); rok && isFile(raw) && !isPage(target) { |
| |
257 | n.Attr[i].Val = base + "/_raw/" + raw |
| |
258 | } else { |
| |
259 | n.Attr[i].Val = base + "/" + target |
| |
260 | } |
| 253 | } |
261 | } |
| 254 | } |
262 | } |
| 255 | } |
263 | } |
internal/httpd/wiki_test.go
+2
| @@ -41,12 +41,14 @@ func TestRewriteWikiLinksInSubfolder(t *testing.T) { |
| 41 | pages := map[string]bool{"Admin": true, "Architecture/Identity": true} |
41 | pages := map[string]bool{"Admin": true, "Architecture/Identity": true} |
| 42 | files := map[string]bool{"diagrams/a.svg": true, "Architecture/b.svg": true} |
42 | files := map[string]bool{"diagrams/a.svg": true, "Architecture/b.svg": true} |
| 43 | in := template.HTML(`<a href="Identity.org">i</a><a href="Admin.org">a</a>` + |
43 | in := template.HTML(`<a href="Identity.org">i</a><a href="Admin.org">a</a>` + |
| |
44 | `<a href="b.svg">diagram</a>` + |
| 44 | `<img src="b.svg"><img src="diagrams/a.svg"><a href="https://x.test/">x</a>`) |
45 | `<img src="b.svg"><img src="diagrams/a.svg"><a href="https://x.test/">x</a>`) |
| 45 | out := string(rewriteWikiLinks(in, p, "Architecture/Trust", |
46 | out := string(rewriteWikiLinks(in, p, "Architecture/Trust", |
| 46 | func(s string) bool { return pages[s] }, func(s string) bool { return files[s] })) |
47 | func(s string) bool { return pages[s] }, func(s string) bool { return files[s] })) |
| 47 | for _, want := range []string{ |
48 | for _, want := range []string{ |
| 48 | `href="/krz/gitbay/wiki/Architecture/Identity"`, |
49 | `href="/krz/gitbay/wiki/Architecture/Identity"`, |
| 49 | `href="/krz/gitbay/wiki/Admin"`, |
50 | `href="/krz/gitbay/wiki/Admin"`, |
| |
51 | `href="/krz/gitbay/wiki/_raw/Architecture/b.svg"`, |
| 50 | `src="/krz/gitbay/wiki/_raw/Architecture/b.svg"`, |
52 | `src="/krz/gitbay/wiki/_raw/Architecture/b.svg"`, |
| 51 | `src="/krz/gitbay/wiki/_raw/diagrams/a.svg"`, |
53 | `src="/krz/gitbay/wiki/_raw/diagrams/a.svg"`, |
| 52 | `href="https://x.test/"`, |
54 | `href="https://x.test/"`, |