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.

Code

392 commit(s) on main

Merge change request 01M70WES5ZZDJ6RP226WB11BBZ: Let people rename and remove their own passkeys keenan · 22m ago 4b8c9e1d
history blame raw 2.6 KiB
1package 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
12import (
13 "html/template"
14 "net/url"
15 "strings"
16
17 "rodent.software/vole/forge/identity"
18 "rodent.software/vole/internal/format"
19 "rodent.software/vole/internal/lang"
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.
25func (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.
29 "since": humanSince,
30 "short": format.SHA,
31 "num": numberLabel,
32 "bytes": format.Bytes,
33 "duration": format.Duration,
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,
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
50 // Chrome. `who` renders an account name and `user` the same name with the
51 // profile it belongs to; `nav` is the repository header's data,
52 // `icon`/`fileicon`/`fileclass` choose inline SVG and its colour.
53 "who": w.who,
54 "user": w.userRef,
55 "nav": w.repoNav,
56 "icon": icon,
57 "fileicon": fileIcon,
58 "fileclass": lang.Class,
59
60 // People. The two pickers are the only widgets a page builds from data
61 // rather than a fragment.
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.
67 "treeContext": treeContext,
68 "commitTreeContext": commitTreeContext,
69 "pathjoin": joinPath,
70 }
71}
72