1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package template_test
6
7import (
8	"fmt"
9	"html/template"
10	"log"
11	"os"
12	"strings"
13)
14
15func Example() {
16	const tpl = `
17<!DOCTYPE html>
18<html>
19	<head>
20		<meta charset="UTF-8">
21		<title>{{.Title}}</title>
22	</head>
23	<body>
24		{{range .Items}}<div>{{ . }}</div>{{else}}<div><strong>no rows</strong></div>{{end}}
25	</body>
26</html>`
27
28	check := func(err error) {
29		if err != nil {
30			log.Fatal(err)
31		}
32	}
33	t, err := template.New("webpage").Parse(tpl)
34	check(err)
35
36	data := struct {
37		Title string
38		Items []string
39	}{
40		Title: "My page",
41		Items: []string{
42			"My photos",
43			"My blog",
44		},
45	}
46
47	err = t.Execute(os.Stdout, data)
48	check(err)
49
50	noItems := struct {
51		Title string
52		Items []string
53	}{
54		Title: "My another page",
55		Items: []string{},
56	}
57
58	err = t.Execute(os.Stdout, noItems)
59	check(err)
60
61	// Output:
62	// <!DOCTYPE html>
63	// <html>
64	// 	<head>
65	// 		<meta charset="UTF-8">
66	// 		<title>My page</title>
67	// 	</head>
68	// 	<body>
69	// 		<div>My photos</div><div>My blog</div>
70	// 	</body>
71	// </html>
72	// <!DOCTYPE html>
73	// <html>
74	// 	<head>
75	// 		<meta charset="UTF-8">
76	// 		<title>My another page</title>
77	// 	</head>
78	// 	<body>
79	// 		<div><strong>no rows</strong></div>
80	// 	</body>
81	// </html>
82
83}
84
85func Example_autoescaping() {
86	check := func(err error) {
87		if err != nil {
88			log.Fatal(err)
89		}
90	}
91	t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
92	check(err)
93	err = t.ExecuteTemplate(os.Stdout, "T", "<script>alert('you have been pwned')</script>")
94	check(err)
95	// Output:
96	// Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!
97}
98
99func Example_escape() {
100	const s = `"Fran & Freddie's Diner" <tasty@example.com>`
101	v := []any{`"Fran & Freddie's Diner"`, ' ', `<tasty@example.com>`}
102
103	fmt.Println(template.HTMLEscapeString(s))
104	template.HTMLEscape(os.Stdout, []byte(s))
105	fmt.Fprintln(os.Stdout, "")
106	fmt.Println(template.HTMLEscaper(v...))
107
108	fmt.Println(template.JSEscapeString(s))
109	template.JSEscape(os.Stdout, []byte(s))
110	fmt.Fprintln(os.Stdout, "")
111	fmt.Println(template.JSEscaper(v...))
112
113	fmt.Println(template.URLQueryEscaper(v...))
114
115	// Output:
116	// &#34;Fran &amp; Freddie&#39;s Diner&#34; &lt;[email protected]&gt;
117	// &#34;Fran &amp; Freddie&#39;s Diner&#34; &lt;[email protected]&gt;
118	// &#34;Fran &amp; Freddie&#39;s Diner&#34;32&lt;[email protected]&gt;
119	// \"Fran \u0026 Freddie\'s Diner\" \[email protected]\u003E
120	// \"Fran \u0026 Freddie\'s Diner\" \[email protected]\u003E
121	// \"Fran \u0026 Freddie\'s Diner\"32\[email protected]\u003E
122	// %22Fran+%26+Freddie%27s+Diner%2232%3Ctasty%40example.com%3E
123
124}
125
126func ExampleTemplate_Delims() {
127	const text = "<<.Greeting>> {{.Name}}"
128
129	data := struct {
130		Greeting string
131		Name     string
132	}{
133		Greeting: "Hello",
134		Name:     "Joe",
135	}
136
137	t := template.Must(template.New("tpl").Delims("<<", ">>").Parse(text))
138
139	err := t.Execute(os.Stdout, data)
140	if err != nil {
141		log.Fatal(err)
142	}
143
144	// Output:
145	// Hello {{.Name}}
146}
147
148// The following example is duplicated in text/template; keep them in sync.
149
150func ExampleTemplate_block() {
151	const (
152		master  = `Names:{{block "list" .}}{{"\n"}}{{range .}}{{println "-" .}}{{end}}{{end}}`
153		overlay = `{{define "list"}} {{join . ", "}}{{end}} `
154	)
155	var (
156		funcs     = template.FuncMap{"join": strings.Join}
157		guardians = []string{"Gamora", "Groot", "Nebula", "Rocket", "Star-Lord"}
158	)
159	masterTmpl, err := template.New("master").Funcs(funcs).Parse(master)
160	if err != nil {
161		log.Fatal(err)
162	}
163	overlayTmpl, err := template.Must(masterTmpl.Clone()).Parse(overlay)
164	if err != nil {
165		log.Fatal(err)
166	}
167	if err := masterTmpl.Execute(os.Stdout, guardians); err != nil {
168		log.Fatal(err)
169	}
170	if err := overlayTmpl.Execute(os.Stdout, guardians); err != nil {
171		log.Fatal(err)
172	}
173	// Output:
174	// Names:
175	// - Gamora
176	// - Groot
177	// - Nebula
178	// - Rocket
179	// - Star-Lord
180	// Names: Gamora, Groot, Nebula, Rocket, Star-Lord
181}
182