Шаблоны

Определение и использовние шаблонов

Последнее обновление: 02.03.2018

Ранее рассматривалось, как в Go отправлять статические файла, в частности, html-страницы. Определение контента в виде html-страниц довольно удобно: мы используем преимущества html+css+javascript, отделяем представление от основной логики, которая пишется на Go. Однако статические страницы малополезны, когда нам необходимо динамически генерировать некоторый контент на основании различных факторов, например, параметров, переданных через строку запроса. И в этом случае мы можем воспользоваться шаблонами.

Язык Go предоставляет функциональность шаблонов по умолчанию в виде пакета html/template.

Используем протейший шаблон:

package main
import (
	"fmt"
	"net/http"
	"html/template"
)

func main() {
	 
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

		data := "Go Template"
		tmpl, _ := template.New("data").Parse("<h1>{{ .}}</h1>")
		tmpl.Execute(w, data)
	})

	fmt.Println("Server is listening...")
	http.ListenAndServe(":8181", nil)
}

С помощью функции template.New("data") определяется имя шаблона. Затем для установки самого шаблона используется функция Parse("<h1>{{ .}}</h1>"). В данном случае шаблон фактически представляет заголовок h1. Но ключевым элементом здесь является двойная пара фигурных скобок {{ .}}. Они позволяют вводить в разметку html различные данные. Здесь в качестве данных указана точка. Точка указывает на контекст шаблона - то есть все данные, которые переданы шаблону.

Стоит отметить, что функция Parse возвращает два значения: собственно шаблон (в данном случае переменная tmpl) и объект ошибки (при ее возникновении). В данном случае объект ошибки не используется, поэтому вместо него идет прочерк.

Чтобы передать шаблону данные, сгенерировать итоговую html-разметку и отправить ее в ответ на запрос, применяется функция Execute:

tmpl.Execute(w, data)

В данном случае переменная data представляет строку, и это как раз те данные, которые будут вставляться в шаблон вместо точки {{ .}}. Ну а первый параметр - это объект http.ResponseWriter, через который отправляются данные.

В итоге при обращении к приложению мы увидим следующий результат:

Templates in Golang

Шаблон может принимать более сложные данные, которые описываются структурой. Например:

package main
import (
	"fmt"
	"net/http"
	"html/template"
)
type ViewData struct{

	Title string
	Message string
}
func main() {
	 
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

		data := ViewData{
			Title: "World Cup",
			Message: "FIFA will never regret it",
		}
		tmpl := template.Must(template.New("data").Parse(`<div>
			<h1>{{ .Title}}</h1>
			<p>{{ .Message}}</p>
		</div>`))
		tmpl.Execute(w, data)
	})

	fmt.Println("Server is listening...")
	http.ListenAndServe(":8181", nil)
}

Здесь данные, передаваемые в шаблон, описываются структурой ViewData, и данная структура будет представлять контекст шаблона. Поэтому чтобы обратиться к отдельным ее переменным, надо после точки указать название переменной: {{ .Title}}.

Стоит отметить, что названия переменных следует определять с большой буквы.

Так как в данном случае используются сложные данные, то их надо обернуть в функцию template.Must(). Сам код шаблона можно переносить на несколько строк, в этом случае код помещается в косые кавычки. Если код шаблона размещается на одной строке, то можно использовать обычные кавычки.

Результат работы программы:

Complex data in templates in Go

Однако определение шаблона внутри кода на Go - нелучший вариант, особенно когда шаблон содержит много сложной html-разметки, вкрапления стилей и скриптов javascript. Поэтому более оптимально определять шаблоны в виде отдельных файлов. Например, определим в проекте папку templates, а в ней создадим файл index.html.

Определим в index.html следующий код:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{{ .Title}}</title>
    </head>
    <body>
        <h1>{{ .Title}}</h1>
        <p>{{ .Message}}</p>
    </body>
</html>

Используем этот шаблон в коде сервера:

package main
import (
	"fmt"
	"net/http"
	"html/template"
)
type ViewData struct{

	Title string
	Message string
}
func main() {
	 
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

		data := ViewData{
			Title: "World Cup",
			Message: "FIFA will never regret it",
		}
		tmpl, _ := template.ParseFiles("templates/index.html")
		tmpl.Execute(w, data)
	})

	fmt.Println("Server is listening...")
	http.ListenAndServe(":8181", nil)
}

Для получения кода из файла применяется функция template.ParseFiles(), которой передается путь к файлу. Итоговый результат будет почти таким же, как и в предыдущим случае:

Шаблоны html в языке Go
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850