Генерация динамического контента с использованием шаблонов Go

Beginner

This tutorial is from open-source community. Access the source code

Введение

Пакет text/template в Golang предоставляет способ создания динамического контента или показа пользователю настраиваемого вывода. Этот пакет позволяет смешивать статический текст и действия, заключённые в {{...}}, для вставки динамического контента.

Текстовые шаблоны

В этом практическом задании вам нужно продемонстрировать использование пакета 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#",
        })
}

Резюме

В этом практическом задании мы узнали, как использовать пакет text/template для генерации динамического контента. Мы продемонстрировали, как получить доступ к полям структуры, обеспечить условное выполнение для шаблонов и пройти по средам, массивам, картам или каналам.