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.
|
c717d4eb
Keenan Nemetz
13d ago
|
1 | package web |
| 2 | ||
| 3 | // The functions a template may call. They are one list, registered as a set, so | |
| 4 | // a template's vocabulary is finite and reviewable: nothing in a page reaches | |
| 5 | // past these into the package. | |
| 6 | // | |
| 7 | // Two rules keep them honest. Nothing here authorizes anything — a template only | |
| 8 | // renders what a handler already decided. And nothing here is allowed to fail: | |
| 9 | // a template function has no error path, so a helper that cannot answer returns | |
| 10 | // an empty string or a zero value. | |
| 11 | ||
| 12 | import ( | |
| 13 | "html/template" | |
| 14 | "net/url" | |
| 15 | "strings" | |
| 16 | ||
|
d37d301f
Keenan Nemetz
15h ago
|
17 | "rodent.software/vole/forge/identity" |
| 18 | "rodent.software/vole/internal/format" | |
| 19 | "rodent.software/vole/internal/lang" | |
|
c717d4eb
Keenan Nemetz
13d ago
|
20 | ) |
| 21 | ||
| 22 | // templateFuncs is a method rather than a plain map because two helpers need the | |
| 23 | // roster the Web holds. It is called once, in New, before the templates are | |
| 24 | // parsed. | |
| 25 | func (w *Web) templateFuncs() template.FuncMap { | |
| 26 | return template.FuncMap{ | |
| 27 | // Formatting. `since` takes a Unix second so a template does not have to | |
| 28 | // convert; `short` and `bytes` are the same renderings the CLI uses. | |
|
c765ae2e
Keenan Nemetz
13d ago
|
29 | "since": humanSince, |
| 30 | "short": format.SHA, | |
|
e05f1c48
Keenan Nemetz
13d ago
|
31 | "num": numberLabel, |
|
c765ae2e
Keenan Nemetz
13d ago
|
32 | "bytes": format.Bytes, |
| 33 | "duration": format.Duration, | |
|
70c9ad4e
Keenan Nemetz
1h ago
|
34 | // runstatus is the stored status as a reader should see it. The value itself is |
| 35 | // the key the gate and the list filters use. | |
| 36 | "runstatus": runStatusLabel, | |
| 37 | "credid": identity.CredentialIDString, | |
| 38 | "inc": func(i int) int { return i + 1 }, | |
| 39 | "join": strings.Join, | |
|
c717d4eb
Keenan Nemetz
13d ago
|
40 | |
| 41 | // Escaping. They are not interchangeable: `esc` escapes a whole value | |
| 42 | // (a ref or a query value, where a "/" becomes a segment separator), | |
| 43 | // while `pathurl` escapes a slash-separated path segment by segment and | |
| 44 | // keeps the separators. Using one where the other belongs produces a | |
| 45 | // link that looks right and resolves to the wrong object. | |
| 46 | "esc": url.PathEscape, | |
| 47 | "pathurl": pathURL, | |
| 48 | "urlquery": url.QueryEscape, | |
| 49 | ||
|
753cd703
Keenan Nemetz
7d ago
|
50 | // Chrome. `who` renders an account name and `user` the same name with the |
|
28b19c74
Keenan Nemetz
7d ago
|
51 | // profile it belongs to; `nav` is the repository header's data, |
|
a6b42433
Keenan Nemetz
7d ago
|
52 | // `icon`/`fileicon`/`fileclass` choose inline SVG and its colour. |
|
28b19c74
Keenan Nemetz
7d ago
|
53 | "who": w.who, |
| 54 | "user": w.userRef, | |
| 55 | "nav": w.repoNav, | |
| 56 | "icon": icon, | |
| 57 | "fileicon": fileIcon, | |
| 58 | "fileclass": lang.Class, | |
|
c717d4eb
Keenan Nemetz
13d ago
|
59 | |
|
753cd703
Keenan Nemetz
7d ago
|
60 | // People. The two pickers are the only widgets a page builds from data |
| 61 | // rather than a fragment. | |
|
c717d4eb
Keenan Nemetz
13d ago
|
62 | "tokenPicker": tokenPicker, |
| 63 | "rolePicker": newRolePicker, | |
| 64 | ||
| 65 | // The file tree is recursive, so its context is built by a function: | |
| 66 | // a template cannot construct the struct it passes back into itself. | |
|
628d4523
Keenan Nemetz
11d ago
|
67 | "treeContext": treeContext, |
| 68 | "commitTreeContext": commitTreeContext, | |
| 69 | "pathjoin": joinPath, | |
|
c717d4eb
Keenan Nemetz
13d ago
|
70 | } |
| 71 | } |