Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

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 "", ""