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/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Blame · server/web/templatefuncs.go

Line attribution on main · 71 line(s)

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
19h 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
5h 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
8d 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 }