vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Resolve a README's relative links against the file, not the page
796ccd9051ef49f10655088ec39b8dfb844f4124 · Keenan Nemetz · 13d ago · parent 53ff967b
Resolve a README's relative links against the file, not the page A relative link was resolved by the browser against the URL the README happened to be rendered at, so `docs/getting-started.md` reached `/r/<repo>/docs/getting-started.md` from the overview page and 404'd, and the same link broke differently from the code browser. A document that lives in the tree now carries its own path, and its links and images are rewritten after parsing and before rendering: markdown opens the preview, other files open the source, images point at the raw route, a directory opens the tree, and `.`/`..` resolve the way a reader expects with climbing clamped at the repository root. A destination that already names somewhere — a scheme, `//host`, a site-absolute path, a bare `#anchor` or `?query` — is left alone, and so is any document with no place in a tree, such as an issue body or a comment. The rewrite works on the parsed tree rather than on the markdown text, so reference-style links are covered too, and the source view still shows the file's bytes unchanged. Refs #01M5XF52R132A88C6WEQ6H6BK6
server/web/overview.go +6−3
| @@ -73,7 +73,7 @@ func (w *Web) Overview(rw http.ResponseWriter, r *http.Request) { | |||
| 73 | 73 | recentRuns, _ = w.Runs.Recent(m.Name, 5) | |
| 74 | 74 | } | |
| 75 | 75 | ||
| 76 | readme, readmeName := w.readmeAt(m, commit) | ||
| 76 | readme, readmeName := w.readmeAt(m, ref, commit) | ||
| 77 | 77 | site := "" | |
| 78 | 78 | if w.Cfg.PagesDomain != "" { | |
| 79 | 79 | site = "http://" + m.Name + "." + w.Cfg.PagesDomain | |
| @@ -114,13 +114,16 @@ func (w *Web) Overview(rw http.ResponseWriter, r *http.Request) { | |||
| 114 | 114 | ||
| 115 | 115 | // readmeAt returns the rendered README and the name it was found under. The name | |
| 116 | 116 | // is shown above the body: a rendered file with no filename is harder to trust. | |
| 117 | func (w *Web) readmeAt(m *repo.Meta, commit string) (template.HTML, string) { | ||
| 117 | // The ref travels with it because a relative link in the README has to resolve to | ||
| 118 | // a URL under the branch the reader is looking at. | ||
| 119 | func (w *Web) readmeAt(m *repo.Meta, ref, commit string) (template.HTML, string) { | ||
| 118 | 120 | if commit == "" { | |
| 119 | 121 | return "", "" | |
| 120 | 122 | } | |
| 121 | 123 | for _, name := range []string{"README.md", "readme.md", "Readme.md", "README.markdown"} { | |
| 122 | 124 | if data, err := m.Git().BlobAt(commit, name); err == nil { | |
| 123 | return w.renderMarkdown(m.Name, string(data)), name | ||
| 125 | doc := treeDoc{Repo: m.Name, Ref: ref, Path: name} | ||
| 126 | return w.renderTreeMarkdown(doc, string(data)), name | ||
| 124 | 127 | } | |
| 125 | 128 | } | |
| 126 | 129 | return "", "" | |