internal/web/funcs.go
83 lines · 2164 bytes
1package web
2
3import (
4 "fmt"
5 "html/template"
6 "net/url"
7 "strconv"
8 "strings"
9
10 "gitbay.org/cmc/gallery/internal/library"
11 "gitbay.org/cmc/gallery/internal/render"
12)
13
14var funcs = template.FuncMap{
15 "albumURL": albumURL,
16 "photoURL": photoURL,
17 "imgURL": imgURL,
18 "srcset": srcset,
19 "preloadSrcset": preloadSrcset,
20 "ar": aspect,
21 "exif": exifLine,
22 "add": func(a, b int) int { return a + b },
23}
24
25func albumURL(a *library.Album) string {
26 return "/" + url.PathEscape(a.Slug) + "/"
27}
28
29func photoURL(it *library.Item) string {
30 return "/" + url.PathEscape(it.Album) + "/" + url.PathEscape(it.Name) + "/"
31}
32
33func imgURL(it *library.Item, w int) string {
34 return fmt.Sprintf("/img/%s/%s/%d.jpg?v=%d", url.PathEscape(it.Album), url.PathEscape(it.Name), w, it.ModTime.UnixNano())
35}
36
37// srcset lists allowed widths up to the first one that reaches the source width.
38func srcset(it *library.Item) string {
39 var parts []string
40 for _, w := range render.Widths {
41 actual := w
42 reached := it.Meta.Width > 0 && w >= it.Meta.Width
43 if reached {
44 actual = it.Meta.Width
45 }
46 parts = append(parts, fmt.Sprintf("%s %dw", imgURL(it, w), actual))
47 if reached {
48 break
49 }
50 }
51 return strings.Join(parts, ", ")
52}
53
54// preloadSrcset renders the whole imagesrcset attribute: html/template treats
55// any unknown attribute containing "src" as a single URL and would escape the
56// spaces and commas a srcset list needs.
57func preloadSrcset(it *library.Item) template.HTMLAttr {
58 return template.HTMLAttr(`imagesrcset="` + template.HTMLEscapeString(srcset(it)) + `"`)
59}
60
61func aspect(it *library.Item) string {
62 if it.Meta.Height == 0 {
63 return "1"
64 }
65 return strconv.FormatFloat(float64(it.Meta.Width)/float64(it.Meta.Height), 'f', 4, 64)
66}
67
68func exifLine(it *library.Item) string {
69 m := it.Meta
70 var parts []string
71 for _, s := range []string{m.Camera, m.Lens, m.Aperture, m.Shutter} {
72 if s != "" {
73 parts = append(parts, s)
74 }
75 }
76 if m.ISO > 0 {
77 parts = append(parts, "ISO "+strconv.Itoa(m.ISO))
78 }
79 if !m.Taken.IsZero() {
80 parts = append(parts, m.Taken.Format("2006-01-02"))
81 }
82 return strings.Join(parts, " · ")
83}