Этот сайт использует cookies. Продолжение работы с сайтом означает, что Вы согласны!
Веб-сервер на Go. Шаблоны
Очень часто мы используем не статические страницы, а генерируем некоторое содержимое на основе изменяемых данных. Например, страница пользователя одна и та же, но вот данные, отображаемые на ней, зависят от конкретного пользователя. Создать динамическую страницу на основе шаблона позволяют функции из пакета html/template
:
import "html/template"
Для загрузки шаблона из файла предназначена функция ParseFiles()
из пакета html/template
. Формат функции:
template.ParseFiles(filenames ...string) (*template.Template, error)
Передать данные в загруженный шаблон позволяет метод Execute()
. Формат метода:
(*template.Template).Execute(wr io.Writer, data interface{}) error
Во втором параметре мы можем передать структуру с данными. Подставить значение поля структуры внутри шаблона позволяет следующая инструкция:
{{ .Название_поля }}
Например, подставим значение поля Name
:
{{ .Name }}
Давайте в файл C:\book\index.html
добавим шаблон, приведенный в листинге 20.8.
Листинг 20.8. Содержимое файла C:\book\index.html
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>{{ .Title }}</title>
</head>
<body>
<h1>{{ .H1 }}</h1>
<p>{{ .Msg }}</p>
<ul>
{{range .Users}}
<li>Имя: {{ .Name }}, возраст: {{ .Age }}</li>
{{end}}
</ul>
{{if .Test}}
<p>Test = true</p>
{{else}}
<p>Test = false</p>
{{end}}
</body>
</html>
Как видно из кода листинга 20.8, внутри шаблона мы можем использовать циклы:
{{range .Users}}
<li>Имя: {{ .Name }}, возраст: {{ .Age }}</li>
{{end}}
а также условные инструкции:
{{if .Test}}
<p>Test = true</p>
{{else}}
<p>Test = false</p>
{{end}}
Теперь загрузим шаблон и подставим в него значения (листинг 20.9).
Листинг 20.9. Загрузка шаблона из файла
package main
import (
"fmt"
"html/template"
"net/http"
)
type Data struct {
Title string
H1 string
Msg string
Users []User
Test bool
}
type User struct {
Name string
Age int
}
func main() {
http.HandleFunc("/",
func(rw http.ResponseWriter, r *http.Request) {
rw.Header().Add("Server", "MyServer 1.0")
data := Data{
Title: "Заголовок страницы <title>",
H1: "Текст заголовка <h1>",
Msg: "Текст содержимого <p>",
Users: []User{
{Name: "Николай", Age: 25},
{Name: "Сергей", Age: 40},
{Name: "<b>Василий</b>", Age: 16},
},
Test: true,
}
tmpl, err := template.ParseFiles(`C:\book\index.html`)
if err != nil {
rw.Header()["Date"] = nil
http.Error(rw, err.Error(), 404)
return
}
err = tmpl.Execute(rw, data)
if err != nil {
rw.Header()["Date"] = nil
http.Error(rw, err.Error(), 404)
}
})
fmt.Println(http.ListenAndServe(":3000", nil))
}
Открываем веб-браузер и в адресной строке вводим: http://localhost:3000/. Если мы отобразим исходный HTML-код, то увидим код, приведенный в листинге 20.10.
Листинг 20.10. HTML-код после подстановки значений в шаблон
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Заголовок страницы <title></title>
</head>
<body>
<h1>Текст заголовка <h1></h1>
<p>Текст содержимого <p></p>
<ul>
<li>Имя: Николай, возраст: 25</li>
<li>Имя: Сергей, возраст: 40</li>
<li>Имя: <b>Василий</b>, возраст: 16</li>
</ul>
<p>Test = true</p>
</body>
</html>
Обратите внимание: после подстановки все специальные символы были заменены HTML-эквивалентами:
<h1>Текст заголовка <h1></h1>
Если в шаблон нужно подставлять HTML-код, то вместо пакета html/template
нужно использовать пакет text/template
. Функционал у пакетов одинаковый, поэтому в листинге 20.9 достаточно заменить инструкцию:
import (
"fmt"
"html/template"
"net/http"
)
следующим кодом:
import (
"fmt"
"net/http"
"text/template"
)
Перезапускаем сервер и обновляем страницу http://localhost:3000/. Если мы отобразим исходный HTML-код, то увидим код, приведенный в листинге 20.11.
Листинг 20.11. HTML-код после подстановки значений в шаблон
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Заголовок страницы <title></title>
</head>
<body>
<h1>Текст заголовка <h1></h1>
<p>Текст содержимого <p></p>
<ul>
<li>Имя: Николай, возраст: 25</li>
<li>Имя: Сергей, возраст: 40</li>
<li>Имя: <b>Василий</b>, возраст: 16</li>
</ul>
<p>Test = true</p>
</body>
</html>
В результате данные были подставлены как есть, без какой-либо замены специальных символов:
<h1>Текст заголовка <h1></h1>
В результате мы получили не валидный HTML-код. Помните, что при использовании пакета text/template
заботиться о замене специальных символов HTML-эквивалентами нужно самостоятельно, иначе можно получить не валидный HTML-код или зловредный код на языке JavaScript, который открывает диалоговое окно в бесконечном цикле или ворует конфиденциальные данные. Не подставляйте в текстовый шаблон данные, полученные из неизвестного источника. Пользуйтесь в этом случае функционалом пакета html/template
.
Помощь сайту
ЮMoney (Yandex-деньги): 410011140483022
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов