-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample_funcmap_test.go
More file actions
128 lines (110 loc) · 2.95 KB
/
example_funcmap_test.go
File metadata and controls
128 lines (110 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package temple_test
import (
"context"
"html/template"
"log/slog"
"os"
"strings"
"impractical.co/temple"
)
type FuncMapSite struct {
// anonymously embedding a *CachedSite makes MySite a Site implementation
*temple.CachedSite
// a configurable title for our site
Title string
}
func (FuncMapSite) FuncMap(_ context.Context) template.FuncMap {
// these functions will be available to all components and pages
return template.FuncMap{
"applesAndOranges": func(input []string) []string {
for pos, fruit := range input {
if strings.ToLower(fruit) == "apples" {
input[pos] = "oranges"
}
}
return input
},
}
}
type FuncMapHomePage struct {
Name string
Fruits []string
Layout FuncMapLayout
}
func (FuncMapHomePage) Templates(_ context.Context) []string {
return []string{"home.html.tmpl"}
}
func (page FuncMapHomePage) UseComponents(_ context.Context) []temple.Component {
return []temple.Component{
page.Layout,
}
}
func (FuncMapHomePage) Key(_ context.Context) string {
return "home.html.tmpl"
}
func (page FuncMapHomePage) ExecutedTemplate(_ context.Context) string {
return page.Layout.BaseTemplate()
}
func (FuncMapHomePage) FuncMap(_ context.Context) template.FuncMap {
return template.FuncMap{
// this function is only available to the homepage
"humanize": func(input []string) string {
if len(input) < 1 {
return ""
}
if len(input) < 2 {
return strings.Join(input, " and ")
}
input[len(input)-1] = "and " + input[len(input)-1]
return strings.Join(input, ", ")
},
}
}
type FuncMapLayout struct {
}
func (layout FuncMapLayout) Templates(_ context.Context) []string {
return []string{layout.BaseTemplate()}
}
func (FuncMapLayout) BaseTemplate() string {
return "base.html.tmpl"
}
func ExampleRender_funcMaps() {
// normally you'd use something like embed.FS or os.DirFS for this
// for example purposes, we're just hardcoding values
var templates = staticFS{
"home.html.tmpl": `{{ define "body" }}Hello, {{ .Page.Name }}. This is my home page. I like {{ humanize (applesAndOranges .Page.Fruits) }}.{{ end }}`,
"base.html.tmpl": `
<!doctype html>
<html lang="en">
<head>
<title>{{ .Site.Title }}</title>
{{- .CSS -}}
{{- .HeaderJS -}}
</head>
<body>
{{ block "body" . }}{{ end }}
{{- .FooterJS -}}
</body>
</html>`,
}
// usually the context comes from the request, but here we're building it from scratch and adding a logger
ctx := temple.LoggingContext(context.Background(), slog.Default())
site := FuncMapSite{
CachedSite: temple.NewCachedSite(templates),
Title: "My Example Site",
}
page := FuncMapHomePage{
Name: "Visitor",
Fruits: []string{"apples", "bananas", "oranges"},
Layout: FuncMapLayout{},
}
temple.Render(ctx, os.Stdout, site, page)
//Output:
// <!doctype html>
// <html lang="en">
// <head>
// <title>My Example Site</title></head>
// <body>
// Hello, Visitor. This is my home page. I like oranges, bananas, and oranges.</body>
// </html>
}