Текстовые шаблоны
В этом практическом задании вам нужно продемонстрировать использование пакета text/template
для генерации динамического контента.
- Используйте пакет
text/template
для генерации динамического контента.
- Используйте функцию
template.Must
, чтобы программа завершилась с ошибкой (panic
), если функция Parse
возвращает ошибку.
- Используйте действие
{{.FieldName}}
для доступа к полям структуры.
- Используйте действие
{{if.. -}} yes {{else -}} no {{end}}\n
, чтобы обеспечить условное выполнение шаблонов.
- Используйте действие
{{range.}}{{.}} {{end}}\n
, чтобы пройти по средам, массивам, картам или каналам.
$ go run templates.go
Value: some text
Value: 5
Value: [Go Rust C++ C#]
Name: Jane Doe
Name: Mickey Mouse
yes
no
Range: Go Rust C++ C#
Ниже представлен полный код:
// Go предоставляет встроенную поддержку для создания динамического контента или показа настраиваемого
// вывода пользователю с использованием пакета `text/template`. Родственный пакет
// под названием `html/template` предоставляет ту же API, но имеет дополнительные функции безопасности
// и должен использоваться для генерации HTML.
package main
import (
"os"
"text/template"
)
func main() {
// Мы можем создать новый шаблон и разобрать его тело из
// строки.
// Шаблоны представляют собой смесь статического текста и "действий", заключённых в
// `{{...}}`, которые используются для динамического вставки контента.
t1 := template.New("t1")
t1, err := t1.Parse("Value is {{.}}\n")
if err!= nil {
panic(err)
}
// Альтернативно мы можем использовать функцию `template.Must`, чтобы
// программа завершилась с ошибкой (`panic`), если `Parse` возвращает ошибку. Это особенно
// полезно для шаблонов, инициализированных в глобальной области видимости.
t1 = template.Must(t1.Parse("Value: {{.}}\n"))
// Выполнив шаблон, мы генерируем его текст с
// конкретными значениями для его действий. Действие `{{.}}` заменяется
// значением, переданным в качестве параметра в `Execute`.
t1.Execute(os.Stdout, "some text")
t1.Execute(os.Stdout, 5)
t1.Execute(os.Stdout, []string{
"Go",
"Rust",
"C++",
"C#",
})
// Вспомогательная функция, которую мы будем использовать ниже.
Create := func(name, t string) *template.Template {
return template.Must(template.New(name).Parse(t))
}
// Если данные представляют собой структуру, мы можем использовать действие `{{.FieldName}}`, чтобы получить доступ
// к её полям. Поля должны быть экспортируемыми, чтобы быть доступными при выполнении шаблона.
t2 := Create("t2", "Name: {{.Name}}\n")
t2.Execute(os.Stdout, struct {
Name string
}{"Jane Doe"})
// То же самое относится к картам; при использовании карточек нет ограничений на регистр имен ключей.
t2.Execute(os.Stdout, map[string]string{
"Name": "Mickey Mouse",
})
// if/else обеспечивают условное выполнение для шаблонов. Значение считается
// ложным, если это значение по умолчанию типа, например 0, пустая строка,
// нулевой указатель и т.д.
// Этот пример демонстрирует другую
// особенность шаблонов: использование `-` в действиях для удаления пробельных символов.
t3 := Create("t3",
"{{if.. -}} yes {{else -}} no {{end}}\n")
t3.Execute(os.Stdout, "not empty")
t3.Execute(os.Stdout, "")
// Блоки range позволяют нам перебирать срезы, массивы, карты или каналы. Внутри
// блока range `{{.}}` устанавливается в текущий элемент итерации.
t4 := Create("t4",
"Range: {{range.}}{{.}} {{end}}\n")
t4.Execute(os.Stdout,
[]string{
"Go",
"Rust",
"C++",
"C#",
})
}