2019-12-10 02:02:15 -05:00
|
|
|
// Copyright 2015 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
2022-03-16 03:48:16 -04:00
|
|
|
//go:build go1.13
|
2019-12-10 02:02:15 -05:00
|
|
|
// +build go1.13
|
|
|
|
|
|
|
|
package template_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
template "github.com/gohugoio/hugo/tpl/internal/go_templates/htmltemplate"
|
|
|
|
)
|
|
|
|
|
|
|
|
func Example() {
|
|
|
|
const tpl = `
|
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
<title>{{.Title}}</title>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
{{range .Items}}<div>{{ . }}</div>{{else}}<div><strong>no rows</strong></div>{{end}}
|
|
|
|
</body>
|
|
|
|
</html>`
|
|
|
|
|
|
|
|
check := func(err error) {
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
t, err := template.New("webpage").Parse(tpl)
|
|
|
|
check(err)
|
|
|
|
|
|
|
|
data := struct {
|
|
|
|
Title string
|
|
|
|
Items []string
|
|
|
|
}{
|
|
|
|
Title: "My page",
|
|
|
|
Items: []string{
|
|
|
|
"My photos",
|
|
|
|
"My blog",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
err = t.Execute(os.Stdout, data)
|
|
|
|
check(err)
|
|
|
|
|
|
|
|
noItems := struct {
|
|
|
|
Title string
|
|
|
|
Items []string
|
|
|
|
}{
|
|
|
|
Title: "My another page",
|
|
|
|
Items: []string{},
|
|
|
|
}
|
|
|
|
|
|
|
|
err = t.Execute(os.Stdout, noItems)
|
|
|
|
check(err)
|
|
|
|
|
|
|
|
// Output:
|
|
|
|
// <!DOCTYPE html>
|
|
|
|
// <html>
|
|
|
|
// <head>
|
|
|
|
// <meta charset="UTF-8">
|
|
|
|
// <title>My page</title>
|
|
|
|
// </head>
|
|
|
|
// <body>
|
|
|
|
// <div>My photos</div><div>My blog</div>
|
|
|
|
// </body>
|
|
|
|
// </html>
|
|
|
|
// <!DOCTYPE html>
|
|
|
|
// <html>
|
|
|
|
// <head>
|
|
|
|
// <meta charset="UTF-8">
|
|
|
|
// <title>My another page</title>
|
|
|
|
// </head>
|
|
|
|
// <body>
|
|
|
|
// <div><strong>no rows</strong></div>
|
|
|
|
// </body>
|
|
|
|
// </html>
|
2020-12-03 07:47:43 -05:00
|
|
|
|
2019-12-10 02:02:15 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func Example_autoescaping() {
|
|
|
|
check := func(err error) {
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
|
|
|
|
check(err)
|
|
|
|
err = t.ExecuteTemplate(os.Stdout, "T", "<script>alert('you have been pwned')</script>")
|
|
|
|
check(err)
|
|
|
|
// Output:
|
|
|
|
// Hello, <script>alert('you have been pwned')</script>!
|
|
|
|
}
|
|
|
|
|
|
|
|
func Example_escape() {
|
|
|
|
const s = `"Fran & Freddie's Diner" <tasty@example.com>`
|
2022-03-16 03:48:16 -04:00
|
|
|
v := []any{`"Fran & Freddie's Diner"`, ' ', `<tasty@example.com>`}
|
2019-12-10 02:02:15 -05:00
|
|
|
|
|
|
|
fmt.Println(template.HTMLEscapeString(s))
|
|
|
|
template.HTMLEscape(os.Stdout, []byte(s))
|
|
|
|
fmt.Fprintln(os.Stdout, "")
|
|
|
|
fmt.Println(template.HTMLEscaper(v...))
|
|
|
|
|
|
|
|
fmt.Println(template.JSEscapeString(s))
|
|
|
|
template.JSEscape(os.Stdout, []byte(s))
|
|
|
|
fmt.Fprintln(os.Stdout, "")
|
|
|
|
fmt.Println(template.JSEscaper(v...))
|
|
|
|
|
|
|
|
fmt.Println(template.URLQueryEscaper(v...))
|
|
|
|
|
|
|
|
// Output:
|
|
|
|
// "Fran & Freddie's Diner" <tasty@example.com>
|
|
|
|
// "Fran & Freddie's Diner" <tasty@example.com>
|
|
|
|
// "Fran & Freddie's Diner"32<tasty@example.com>
|
2020-05-23 09:32:27 -04:00
|
|
|
// \"Fran \u0026 Freddie\'s Diner\" \u003Ctasty@example.com\u003E
|
|
|
|
// \"Fran \u0026 Freddie\'s Diner\" \u003Ctasty@example.com\u003E
|
|
|
|
// \"Fran \u0026 Freddie\'s Diner\"32\u003Ctasty@example.com\u003E
|
2019-12-10 02:02:15 -05:00
|
|
|
// %22Fran+%26+Freddie%27s+Diner%2232%3Ctasty%40example.com%3E
|
2020-12-03 07:47:43 -05:00
|
|
|
|
2019-12-10 02:02:15 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func ExampleTemplate_Delims() {
|
|
|
|
const text = "<<.Greeting>> {{.Name}}"
|
|
|
|
|
|
|
|
data := struct {
|
|
|
|
Greeting string
|
|
|
|
Name string
|
|
|
|
}{
|
|
|
|
Greeting: "Hello",
|
|
|
|
Name: "Joe",
|
|
|
|
}
|
|
|
|
|
|
|
|
t := template.Must(template.New("tpl").Delims("<<", ">>").Parse(text))
|
|
|
|
|
|
|
|
err := t.Execute(os.Stdout, data)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Output:
|
|
|
|
// Hello {{.Name}}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The following example is duplicated in text/template; keep them in sync.
|
|
|
|
|
|
|
|
func ExampleTemplate_block() {
|
|
|
|
const (
|
|
|
|
master = `Names:{{block "list" .}}{{"\n"}}{{range .}}{{println "-" .}}{{end}}{{end}}`
|
|
|
|
overlay = `{{define "list"}} {{join . ", "}}{{end}} `
|
|
|
|
)
|
|
|
|
var (
|
|
|
|
funcs = template.FuncMap{"join": strings.Join}
|
|
|
|
guardians = []string{"Gamora", "Groot", "Nebula", "Rocket", "Star-Lord"}
|
|
|
|
)
|
|
|
|
masterTmpl, err := template.New("master").Funcs(funcs).Parse(master)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
overlayTmpl, err := template.Must(masterTmpl.Clone()).Parse(overlay)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
if err := masterTmpl.Execute(os.Stdout, guardians); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
if err := overlayTmpl.Execute(os.Stdout, guardians); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
// Output:
|
|
|
|
// Names:
|
|
|
|
// - Gamora
|
|
|
|
// - Groot
|
|
|
|
// - Nebula
|
|
|
|
// - Rocket
|
|
|
|
// - Star-Lord
|
|
|
|
// Names: Gamora, Groot, Nebula, Rocket, Star-Lord
|
|
|
|
}
|