Шпаргалка по html/template в Go
html/template - это пакет Go для безопасного создания HTML-выхода с автоматическим экранированием.
Инициализация шаблона
import "html/template"
// Создание нового шаблона
tmpl := template.New("templateName")
// Парсинг шаблона из строки
tmpl, err := template.New("test").Parse(`<h1>{{.Title}}</h1>`)
// Парсинг шаблона из файла
tmpl, err := template.ParseFiles("template.html")
// Парсинг нескольких файлов
tmpl, err := template.ParseGlob("templates/*.html")
Основные конструкции в шаблоне
1. Вывод значения
<!-- Простой вывод -->
<p>{{.UserName}}</p>
<!-- Вывод с экранированием HTML -->
<p>{{.UserComment}}</p>
<!-- Вывод без экранирования (осторожно!) -->
<p>{{.SafeHTML | html}}</p>
2. Условия
{{if .User}}
<p>Welcome, {{.User}}!</p>
{{else}}
<p>Please log in.</p>
{{end}}
{{if eq .Role "admin"}}
<p>Admin dashboard</p>
{{end}}
3. Циклы
<ul>
{{range .Items}}
<li>{{.}}</li>
{{end}}
</ul>
<!-- С индексом -->
<ul>
{{range $index, $item := .Items}}
<li>Item #{{$index}}: {{$item}}</li>
{{end}}
</ul>
<!-- Если слайс пуст -->
{{range .Items}}
{{.}}
{{else}}
<p>No items found</p>
{{end}}
4. Определение переменных
{{$name := .UserName}}
{{$count := len .Items}}
<p>Hello, {{$name}}. You have {{$count}} items.</p>
5. Функции и конвейеры
<!-- Вызов встроенных функций -->
<p>{{printf "Hello, %s" .Name}}</p>
<p>{{len .Items}} items</p>
<p>{{index .Items 0}}</p>
<!-- Конвейер -->
<p>{{.Title | upper | truncate 50}}</p>
6. Вложенные шаблоны
// Определение в коде
tmpl := template.Must(template.New("base").Parse(`
{{define "content"}}Default content{{end}}
<html>
<body>
{{template "content" .}}
</body>
</html>
`))
// Переопределение в другом шаблоне
tmpl2 := template.Must(tmpl.Parse(`{{define "content"}}New content{{end}}`))
<!-- В шаблоне -->
{{template "header" .}}
<!-- С передачей других данных -->
{{template "footer" .FooterData}}
7. Пользовательские функции
funcMap := template.FuncMap{
"upper": strings.ToUpper,
"add": func(a, b int) int { return a + b },
}
tmpl := template.New("test").Funcs(funcMap)
tmpl, err := tmpl.Parse(`{{upper .Name}} {{add 1 2}}`)
Пример полного шаблона
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}} - My Site</title>
</head>
<body>
<header>
{{if .User}}
<p>Welcome, {{.User.Name}} ({{.User.Email}})</p>
{{else}}
<a href="/login">Login</a>
{{end}}
</header>
<nav>
<ul>
{{range .Menu}}
<li><a href="{{.URL}}">{{.Title}}</a></li>
{{end}}
</ul>
</nav>
<main>
{{template "content" .}}
</main>
<footer>
<p>© {{.CurrentYear}} My Company</p>
</footer>
</body>
</html>
Выполнение шаблона
// В память
err := tmpl.Execute(os.Stdout, data)
// В строку
var buf bytes.Buffer
err := tmpl.Execute(&buf, data)
result := buf.String()
// Конкретный шаблон из набора
err := tmpl.ExecuteTemplate(os.Stdout, "templateName", data)
Обработка ошибок
tmpl := template.Must(template.New("").Parse("...")) // паника при ошибке
if err := tmpl.Execute(w, data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
Безопасность
- Автоматическое экранирование HTML/JS/CSS
- Для отключения экранирования используйте типы
template.HTML
,template.JS
,template.CSS
:
type Data struct {
SafeContent template.HTML
}
data := Data{SafeContent: template.HTML("<b>Safe HTML</b>")}